Question address: zoj 3792
The minimum cut is too small .. This question is obviously about cutting edge. If the Forward Arc traffic is 0 after a minimum cut operation, the edge is a cut edge. But what should I do after I find the cut edge .. It was a sudden inspiration when I went to bed at noon .. You can find the maximum stream by using the cut edge .. Set the cut edge traffic to 1, and the rest to be positive infinity. The final traffic is the cut edge with the least need. Then the computation is complete.
This time, we set the upper limit to sink + 1... As a result, WA has 12 hair ..... Sad... Pay attention to it later...
The Code is as follows:
#include <iostream>#include <cstdio>#include <string>#include <cstring>#include <stdlib.h>#include <math.h>#include <ctype.h>#include <queue>#include <map>#include <set>#include <algorithm>using namespace std;const int INF=0x3f3f3f3f;int head[100], source, sink, nv, cnt;int cur[100], num[100], d[100], pre[100];struct node{ int u, v, cap, next;} edge[1000000];void add(int u, int v, int cap){ edge[cnt].v=v; edge[cnt].cap=cap; edge[cnt].next=head[u]; head[u]=cnt++; edge[cnt].v=u; edge[cnt].cap=0; edge[cnt].next=head[v]; head[v]=cnt++;}void bfs(){ memset(num,0,sizeof(num)); memset(d,-1,sizeof(d)); queue<int>q; q.push(sink); d[sink]=0; num[0]=1; while(!q.empty()) { int u=q.front(); q.pop(); for(int i=head[u]; i!=-1; i=edge[i].next) { int v=edge[i].v; if(d[v]==-1) { d[v]=d[u]+1; num[d[v]]++; q.push(v); } } }}int isap(){ memcpy(cur,head,sizeof(cur)); int flow=0, u=pre[source]=source, i; bfs(); while(d[source]<nv) { if(u==sink) { int f=INF, pos; for(i=source; i!=sink; i=edge[cur[i]].v) { if(f>edge[cur[i]].cap) { f=edge[cur[i]].cap; pos=i; } } for(i=source; i!=sink; i=edge[cur[i]].v) { edge[cur[i]].cap-=f; edge[cur[i]^1].cap+=f; } flow+=f; u=pos; } for(i=cur[u]; i!=-1; i=edge[i].next) { if(d[edge[i].v]+1==d[u]&&edge[i].cap) break; } if(i!=-1) { cur[u]=i; pre[edge[i].v]=u; u=edge[i].v; } else { if(--num[d[u]]==0) break; int mind=nv; for(i=head[u]; i!=-1; i=edge[i].next) { if(mind>d[edge[i].v]&&edge[i].cap) { mind=d[edge[i].v]; cur[u]=i; } } d[u]=mind+1; num[d[u]]++; u=pre[u]; } } return flow;}int main(){ int n, m, sum, u, v, w, t, k, i, j; scanf("%d",&t); while(t--) { scanf("%d%d%d%d",&n,&m,&source,&sink); memset(head,-1,sizeof(head)); cnt=0; sum=0; nv=n+1; while(m--) { scanf("%d%d%d",&u,&v,&w); add(u,v,w); add(v,u,w); sum+=w; } int x=isap(); if(x==0) { printf("Inf\n"); continue ; } for(i=0; i<cnt; i+=2) { if(edge[i].cap==0) { edge[i].cap=1; edge[i^1].cap=0; } else { edge[i].cap=INF; edge[i^1].cap=0; } } int tot=isap(); double ans=(sum-x)*1.0/tot; printf("%.2lf\n",ans); } return 0;}