直接套用ISAP模板
我的模板不一定正确…… 不能参考!!!!!
/* TASK:ditch LANG:C++ */ #include <iostream> #include <queue> #include <cstdio> #include <cstring> #include <cstdlib> using namespace std; const int max_ver = 200 + 10; int n, m; struct edge { int ver, cap, flow; edge *next, *rev; edge(){} edge(int _Ver, int _Cap, edge* _Next):ver(_Ver), cap(_Cap), next(_Next), flow(0), rev(NULL){} }*net[max_ver]={NULL}; inline void insert_edge(int s, int t, int cap) { net[s] = new edge(t, cap, net[s]); net[t] = new edge(s, 0, net[t]); net[s] -> rev = net[t]; net[t] -> rev = net[s]; } void init() { scanf("%d%d", &m, &n); while (m--) { int a, b , c; scanf("%d%d%d", &a, &b, &c); insert_edge(a, b, c); } } queue<int>q; int dist[max_ver], numbs[max_ver]; void rev_bfs(int s = 1, int t = n) { q.push(t); for (int i = 1; i <= n; ++ i) dist[i] = 0x7fffffff; memset(numbs, 0, sizeof(numbs)); numbs[0] = 1; q.push(t); dist[t] = 0; while (!q.empty()) { int now = q.front(); q.pop(); for (edge *e = net[now]; e; e = e -> next) { int will = e -> ver; if (dist[will] != 0x7fffffff || e -> rev -> cap == 0) continue; dist[will] = dist[now] + 1; ++ numbs[dist[will]]; q.push(will); } } } edge *CurEdge[max_ver], *revpath[max_ver]; int totflow(0); void augflow(int s = 1, int t = n) { int augflow = 0x7fffffff; for (int i = s; i != t; i = CurEdge[i] -> ver) { //cout<<"["<<i<<"]"<<endl; augflow = min(augflow, CurEdge[i] -> cap); } for (int i = s; i != t; i = CurEdge[i] -> ver) { CurEdge[i] -> cap -= augflow; CurEdge[i] -> rev -> cap += augflow; CurEdge[i] -> flow += augflow; CurEdge[i] -> rev -> flow -= augflow; } totflow += augflow; } void maxflow(int s = 1, int t = n) { int totalflow = 0; for (int i = 1; i <= n; ++ i) CurEdge[i] = net[i];//当前弧优化! int now = s; while (dist[s] < n) // 起点到终点的距离比n小。一旦到n,肯定是到不了。 比如1->2 如果1->2距离是2,肯定是不可能的 { if (now == t) { augflow(); now = s; } edge *e; for (e = CurEdge[now]; e; e = e -> next) if (e -> cap > 0 && dist[now] == dist[e -> ver] + 1) break;//找到一个可行的路 if (e) { CurEdge[now] = e; revpath[e -> ver] = e -> rev; //计算will是从哪里来的,为了回溯 now = e -> ver; }else{ //失败了,显然要回溯 if (0 == (--numbs[dist[now]])) break; //如果一个距离已经没有了。 出现断层了 显然就应该结束了 CurEdge[now] = net[now]; int mindist = n; for (edge *te = net[now]; te; te = te -> next) if (te -> cap >0) mindist = min(mindist, dist[te -> ver]); dist[now] = mindist + 1; ++ numbs[dist[now]]; if (now != s) now = revpath[now] -> ver; } } printf("%d\n", totflow); } int main() { freopen("ditch.in","r",stdin); freopen("ditch.out","w",stdout); init(); rev_bfs(1, n); maxflow(1, n); return 0; }