hdu 4280 Island Transport 最大流dinic算法

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纠结了好久。。

View 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;

}

 

你可能感兴趣的:(dinic)