HDU 4280 Island Transport Posted on 2016-08-13 | In ACM | | Visitors 题目链接HDU 4280解题方法:最大流 题目分析题目大意给出n个岛屿的坐标,以及m条通路,问,从x最小的位置到x最大的位置最多可以运送多少人 解析最大流模版题,注意需要双向加边 代码123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143#include<stdio.h>#include<cstring>#include<algorithm>#include<iostream>#include<cmath>#include<vector>using namespace std;#define mem(x,y) memset(x,y,sizeof(x))#define inf 0x3f3f3f3f#define debug puts("-----")#define maxn 100000+5#define ll long long#define LL long long#define NE 3000#define mx 10005#define ep 1e-2#define pi acos(-1.0)#define mod 1000000007///===================================////#define INF 0x3f3f3f3fnamespace ISAP{ const int Emax = 420900; int n; struct Node { int v; // vertex int cap; // capacity int flow; // current flow in this arc int nxt; } e[Emax * 2]; int g[maxn], fcnt; int st, ed; int dist[maxn], numbs[maxn], q[maxn]; void adde(int u, int v, int c) { e[++fcnt].v = v; e[fcnt].cap = c; e[fcnt].flow = 0; e[fcnt].nxt = g[u]; g[u] = fcnt; e[++fcnt].v = u; e[fcnt].cap = 0; e[fcnt].flow = 0; e[fcnt].nxt = g[v]; g[v] = fcnt; } void init(int src,int sink,int n_) { memset(g, 0, sizeof(g)); fcnt = 1; n=n_; st = src, ed = sink;/*??*/ //n = n + 3; //?????n?????? } void rev_bfs() { int font = 0, rear = 1; for (int i = 0; i <= n; i++) { //n???? dist[i] = maxn; numbs[i] = 0; } q[font] = ed; dist[ed] = 0; numbs[0] = 1; while(font != rear) { int u = q[font++]; for (int i = g[u]; i; i = e[i].nxt) { if (e[i ^ 1].cap == 0 || dist[e[i].v] < maxn) continue; dist[e[i].v] = dist[u] + 1; ++numbs[dist[e[i].v]]; q[rear++] = e[i].v; } } } int maxflow() { rev_bfs(); int u, totalflow = 0; int curg[maxn], revpath[maxn]; for(int i = 0; i <= n; ++i) curg[i] = g[i]; u = st; while(dist[st] < n) { if(u == ed) { // find an augmenting path int augflow = INF; for(int i = st; i != ed; i = e[curg[i]].v) augflow = min(augflow, e[curg[i]].cap); for(int i = st; i != ed; i = e[curg[i]].v) { e[curg[i]].cap -= augflow; e[curg[i] ^ 1].cap += augflow; e[curg[i]].flow += augflow; e[curg[i] ^ 1].flow -= augflow; } totalflow += augflow; u = st; } int i; for(i = curg[u]; i; i = e[i].nxt) if(e[i].cap > 0 && dist[u] == dist[e[i].v] + 1) break; if(i) { // find an admissible arc, then Advance curg[u] = i; revpath[e[i].v] = i ^ 1; u = e[i].v; } else { // no admissible arc, then relabel this vertex if(0 == (--numbs[dist[u]])) break; // GAP cut, Important! curg[u] = g[u]; int mindist = n; for(int j = g[u]; j; j = e[j].nxt) if(e[j].cap > 0) mindist = min(mindist, dist[e[j].v]); dist[u] = mindist + 1; ++numbs[dist[u]]; if(u != st) u = e[revpath[u]].v; // Backtrack } } return totalflow; }}int main(){ int T; scanf("%d",&T); while (T--) { int n,m,x,y,r,l,lx,rx,tmp; scanf("%d%d",&n,&m); l=1,r=1; scanf("%d%*d",&lx); rx = lx; for (int i=2; i<=n; i++) { scanf("%d%*d",&x); if (x<lx) { lx = x; l = i; } if (x>rx) { rx = x; r = i; } } ISAP::init(l, r, n); for (int i=1; i<=m; i++) { scanf("%d%d%d",&x,&y,&tmp); ISAP::adde(x, y, tmp); ISAP::adde(y, x, tmp); } cout<<ISAP::maxflow()<<endl; } }