最大流=最小割 这题是求割边集 dinic求出残余网络 两边dfs分别以源点d找到可达点 再以汇点进行d找到可达汇点的点
如果u,v为割边 那么s->u可达 v->t可达 并且为饱和边
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <queue> 5 #include <algorithm> 6 using namespace std; 7 const int INF = 50000; 8 const int N = 505; 9 #define M 100005 10 struct node 11 { 12 int u,v,next; 13 int w; 14 }edge[M],p[M]; 15 int head[N],t,vis[N],pp[N],dis[N]; 16 int st,en; 17 bool vis1[N],vis2[N]; 18 void init() 19 { 20 t=0; 21 memset(head,-1,sizeof(head)); 22 } 23 void add(int u,int v,int w) 24 { 25 edge[t].u = u; 26 edge[t].v = v; 27 edge[t].w = w; 28 edge[t].next = head[u]; 29 head[u] = t++; 30 edge[t].u = v; 31 edge[t].v = u; 32 edge[t].w = 0; 33 edge[t].next = head[v]; 34 head[v] = t++; 35 } 36 int bfs() 37 { 38 int i,u; 39 int w; 40 memset(dis,0,sizeof(dis)); 41 queue<int>q; 42 q.push(st); 43 dis[st]= 1; 44 while(!q.empty()) 45 { 46 u = q.front(); 47 q.pop(); 48 for(i = head[u] ; i != -1 ; i = edge[i].next) 49 { 50 int v = edge[i].v; 51 w = edge[i].w; 52 if(!dis[v]&&w>0) 53 { 54 dis[v] = dis[u]+1; 55 q.push(v); 56 } 57 } 58 } 59 if(dis[en]>0) return 1; 60 return 0; 61 } 62 int dfs(int u,int te) 63 { 64 int i; 65 int s; 66 if(u==en) return te; 67 int tmp = te; 68 for(i = head[u] ; i != -1 ; i = edge[i].next) 69 { 70 int v = edge[i].v; 71 int w = edge[i].w; 72 if(w>0&&dis[v]==dis[u]+1&&(s=dfs(v,min(te,w)))) 73 { 74 edge[i].w-=s; 75 edge[i^1].w+=s; 76 tmp-=s; 77 } 78 } 79 return te-tmp; 80 } 81 int dinic() 82 { 83 int flow = 0; 84 while(bfs()) 85 { 86 flow+=dfs(st,INF); 87 } 88 return flow; 89 } 90 void dfs1(int u) 91 { 92 int i; 93 for(i = head[u] ; i != -1 ; i= edge[i].next) 94 if(!vis1[edge[i].v]&&edge[i].w>0) 95 { 96 vis1[edge[i].v] = 1; 97 dfs1(edge[i].v); 98 } 99 } 100 void dfs2(int u) 101 { 102 int i; 103 for(i = head[u] ; i != -1 ; i= edge[i].next) 104 { 105 int v = edge[i].v; 106 //cout<<v<<" "<<edge[i].w<<endl; 107 if(!vis2[edge[i].v]&&edge[i^1].w>0) 108 { 109 vis2[edge[i].v] = 1; 110 dfs2(edge[i].v); 111 } 112 } 113 } 114 int main() 115 { 116 int n,m,i; 117 while(scanf("%d%d",&n,&m)!=EOF) 118 { 119 init(); 120 memset(vis1,0,sizeof(vis1)); 121 memset(vis2,0,sizeof(vis2)); 122 for(i = 1 ;i <= m; i++) 123 { 124 int u,v,c; 125 scanf("%d%d%d",&u,&v,&c); 126 u++,v++; 127 add(u,v,c); 128 } 129 st = 1,en = n; 130 int kk = dinic(); 131 //cout<<kk<<endl; 132 vis1[st] = 1; 133 dfs1(st); 134 vis2[en] = 1; 135 dfs2(en); 136 int ans = 0; 137 dinic(); 138 for(i = 0; i < t; i+=2) 139 { 140 int u = edge[i].u; 141 int v = edge[i].v; 142 int w = edge[i].w; 143 //cout<<u<<" "<<v<<" "<<vis1[u]<<" "<<vis2[v]<<endl; 144 if(vis1[u]&&vis2[v]&&w<=0) 145 ans++; 146 } 147 cout<<ans<<endl; 148 } 149 return 0; 150 }