http://acm.hdu.edu.cn/showproblem.php?pid=4280

题意:

给定平面上n个点的坐标,最左边的点为源点,最右边的点为汇点,给出m条边的容量求最大流。

思路:

才开始理解错了题意,For safety, no two routes are cross or overlap and no routes will pass an island except the departing island and the arriving island。以为要处理线段不能相交什么的,不知道怎么做了。原来直接见图套模板即可,题目保证不会相交。为此我和von纠结了好久。。

hdu 4280 Island Transport  最大流dinic算法_最大流hdu 4280 Island Transport  最大流dinic算法_ios_02View Code
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <string>

#define CL(a,num) memset((a),(num),sizeof(a))
#define iabs(x)  ((x) > 0 ? (x) : -(x))
#define Min(a,b) (a) > (b)? (b):(a)
#define Max(a,b) (a) > (b)? (a):(b)

#define ll long long
#define inf 0x7f7f7f7f
#define MOD 100000007
#define lc l,m,rt<<1
#define rc m + 1,r,rt<<1|1
#define pi acos(-1.0)
#define test puts("<------------------->")
#define maxn 100007
#define M 100007
#define N 100007
using namespace std;
//freopen("din.txt","r",stdin);

struct point{
    int x,y;
    int id;
}p[N];

struct node{
    int v,w;
    int next;
}g[M*4 + 10];

int head[N],ct;
int level[N],q[N*100];
int n,m;

void init(){
    ct = 0;
    CL(head,-1);
}
void add(int u,int v,int w){
    g[ct].v = v;
    g[ct].w = w;
    g[ct].next = head[u];
    head[u] = ct++;

    g[ct].v = u;
    g[ct].w = 0;
    g[ct].next = head[v];
    head[v] = ct++;
}
int cmp(point a,point b){
    return a.x < b.x;
}
bool layer(int s,int e){
    int i;
    CL(level,-1);
    level[s] = 0;
    int l,r;
    l = r = 0;
    q[r] = s;
    while (l <= r){
        int u = q[l++];
        for (i = head[u]; i != -1; i = g[i].next){
            int v = g[i].v;
            if (level[v] == -1 && g[i].w > 0){
                level[v] = level[u] + 1;
                q[++r] = v;
                if (v == e) return true;
            }
        }
    }
    return false;
}
int find(int s,int e){
    int i;
    int ans = 0;
    int top = 1;

    while (top){
        int u = (top == 1 ? s : g[q[top - 1]].v);

        if (u == e){
            int MIN = inf,pos;
            for (i = 1; i < top; ++i){
                int tp = q[i];
                if (g[tp].w < MIN){
                    MIN = g[tp].w;
                    pos = i;
                }
            }
            for (i = 1; i < top; ++i){
                int tp = q[i];
                g[tp].w -= MIN;
                g[tp^1].w += MIN;
            }
            ans += MIN;
            top = pos;
        }
        else{
            for (i = head[u]; i != -1; i = g[i].next){
                int v = g[i].v;
                if (g[i].w > 0 && level[v] == level[u] + 1){
                    q[top++] = i;
                    break;
                 }
            }
            if (i == -1){
                top--;
                level[u] = -1;
            }
        }
    }
    return ans;
}
int Dinic(int s,int e){
    int ans = 0;
    while (layer(s,e)) ans += find(s,e);
    return ans;
}
int main(){
    //freopen("din.txt","r",stdin);
    int t,i;
    int x,y,z;
    scanf("%d",&t);
    while (t--){
        init();
        scanf("%d%d",&n,&m);
        for (i = 0; i < n; ++i){
            scanf("%d%d",&p[i].x,&p[i].y);
            p[i].id = i + 1;
        }
        //建图
        for (i = 0; i < m; ++i){
            scanf("%d%d%d",&x,&y,&z);
            add(x,y,z);
            add(y,x,z);
        }
        //排序,找源点汇点
        sort(p,p + n,cmp);
        int s = p[0].id,e = p[n - 1].id;

        printf("%d\n",Dinic(s,e));//模板
    }
    return 0;
}