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