poj 3204
告诉了一个有向图G(V,E)、源点S、汇点T。假设这个网络图的最大流是mflow。那么请问,一共有多少条这样的边:仅仅增加此条边的容量上限,可以使得mflow变大,输出这些边分别是什么。
先跑一遍最大流得到残留网络。
从st深搜残留网络中所有未满流的边,把能到达的点标记。
从en做同样的事。
显然对于一条满足题意的边必有u在st能到达。v在en能到达。
枚举所有边即可。
1 // File Name: 3204.cpp 2 // Author: Missa 3 // Created Time: 2013/4/18 星期四 22:48:07 4 5 #include<iostream> 6 #include<cstdio> 7 #include<cstring> 8 #include<algorithm> 9 #include<cmath> 10 #include<queue> 11 #include<stack> 12 #include<string> 13 #include<vector> 14 #include<cstdlib> 15 #include<map> 16 #include<set> 17 using namespace std; 18 #define CL(x,v) memset(x,v,sizeof(x)); 19 #define R(i,st,en) for(int i=st;i<en;++i) 20 #define LL long long 21 22 const int inf = 0x3f3f3f3f; 23 const int maxn = 501; 24 const int maxm = 5001; 25 struct Edge 26 { 27 int v, c, next;//指向点,流量,下一个点 28 }p[maxm << 1]; 29 int head[maxn], e; 30 int d[maxn], cur[maxn];//层次记录,当前弧优化 31 int n, m, st, en; 32 inline void init() 33 { 34 e = 0; 35 memset(head, -1, sizeof(head)); 36 } 37 inline void addEdge(int u, int v, int c) 38 { 39 p[e].v = v; p[e].c = c; 40 p[e].next = head[u];head[u] = e++; 41 p[e].v = u; p[e].c = 0; //无向图时逆边赋值流量cap,有向图时赋值0. 42 p[e].next = head[v];head[v] = e++; 43 } 44 inline int bfs(int st, int en) 45 { 46 queue <int> q; 47 memset(d, 0, sizeof(d)); 48 d[st] = 1; 49 q.push(st); 50 while (!q.empty()) 51 { 52 int u = q.front(); q.pop(); 53 for (int i = head[u]; i != -1; i = p[i].next) 54 { 55 if (p[i].c > 0 && !d[p[i].v]) 56 { 57 d[p[i].v] = d[u] + 1; 58 q.push(p[i].v); 59 } 60 } 61 } 62 return d[en]; 63 } 64 inline int dfs(int u, int a)//a表示流量 65 { 66 if (u == en || a == 0) return a; 67 int f, flow = 0; 68 for (int& i = cur[u]; i != -1; i = p[i].next) 69 { 70 if (d[u] + 1 == d[p[i].v] && (f = dfs(p[i].v,min(a,p[i].c))) > 0) 71 { 72 p[i].c -= f; 73 p[i^1].c += f; 74 flow += f; 75 a -= f; 76 if (!a) break; 77 } 78 } 79 return flow; 80 } 81 inline int dinic(int st, int en) 82 { 83 int res = 0; 84 while (bfs(st, en)) 85 { 86 for (int i = 0; i <= n; ++i) 87 cur[i] = head[i]; 88 res += dfs(st, inf); 89 } 90 return res; 91 } 92 int vis[maxn]; 93 inline void dfs1(int u) 94 { 95 vis[u] = 1;//src可达 96 for (int i = head[u]; i != -1; i = p[i].next) 97 if (vis[p[i].v] == 0 && p[i].c ) 98 dfs1(p[i].v); 99 } 100 inline void dfs2(int u) 101 { 102 vis[u] = 2; 103 for (int i = head[u]; i != -1; i = p[i].next) 104 if (vis[p[i].v] == 0 && p[i^1].c ) 105 dfs2(p[i].v); 106 } 107 int main() 108 { 109 while(~scanf("%d%d",&n,&m)) 110 { 111 init(); 112 st = 1, en = n; 113 for (int i =1 ; i <= m; ++i) 114 { 115 int u , v, c; 116 scanf("%d%d%d",&u,&v,&c); 117 addEdge(u + 1, v + 1, c); 118 } 119 int ans = dinic(st, en); 120 memset(vis, 0, sizeof(vis)); 121 dfs1(st);dfs2(en); 122 ans = 0; 123 for (int i = 0; i < e; i += 2)//i += 2. 124 if (vis[p[i].v] == 2 && vis[p[i^1].v] == 1) 125 ans ++; 126 printf("%d\n",ans); 127 } 128 return 0; 129 }