InputThe input contains several test cases and the first line is the total number of cases T (1≤T≤300) T (1≤T≤300) .
Each case describes a network G G
, and the first line contains two integers n (2≤n≤200) n (2≤n≤200)
and m (0≤m≤1000) m (0≤m≤1000)
indicating the sizes of nodes and edges. All nodes in the network are labelled from 1 1
to n n
.
The second line contains two different integers s s
and t (1≤s,t≤n) t (1≤s,t≤n)
corresponding to the source and sink.
Each of the next m m
lines contains three integers u,v u,v
and w (1≤w≤255) w (1≤w≤255)
describing a directed edge from node u u
to v v
with capacity w w
.OutputFor each test case, output the smallest size of all minimum cuts in a line.Sample Input
2 4 5 1 4 1 2 3 1 3 1 2 3 1 2 4 1 3 4 2 4 5 1 4 1 2 3 1 3 1 2 3 1 2 4 1 3 4 3
Sample Output
2 3
题意:给定N点M边的网络,求最小割边的数量,使得S与T不连通。
思路:百度才知道的。用了数学的思想来搞的,每条边的容量V=V*(M+1)+1,最后的最小割=ans/(M+1),最小割边=ans%(M+1);
简单说明:肯定是对的,因为V=V*(M+1)+1的这个尾巴“1”数量少于M+1,所以ans/(M+1)显然不会进位,就等于最小割;那么尾巴1的个数就是边数了,ans膜一下(M+1)最小割求出的最少边数。
#include<bits/stdc++.h> using namespace std; const int maxn=2010; const int inf=0x7fffffff; int vd[maxn],dis[maxn],Laxt[maxn],Next[maxn],To[maxn],V[maxn]; int N,M,cnt,ans,S,T; void update() { for(int i=1;i<=N;i++) Laxt[i]=vd[i]=dis[i]=0; for(int i=1;i<=cnt;i++) V[i]=0; cnt=1; ans=0; } void add(int u,int v,int c) { Next[++cnt]=Laxt[u];Laxt[u]=cnt;To[cnt]=v;V[cnt]=c; Next[++cnt]=Laxt[v];Laxt[v]=cnt;To[cnt]=u;V[cnt]=0; } int sap(int u,int flow) { int tmp,delta=0; if(flow==0||u==T) return flow; for(int i=Laxt[u];i;i=Next[i]) { if(dis[To[i]]+1==dis[u]&&V[i]>0){ tmp=sap(To[i],min(flow-delta,V[i])); V[i]-=tmp; V[i^1]+=tmp; delta+=tmp; if(delta==flow||dis[S]>=N) return delta; } } vd[dis[u]]--; if(vd[dis[u]]==0) dis[S]=N; vd[++dis[u]]++; return delta; } int main() { int C,i,j,u,v,w; scanf("%d",&C); while(C--){ scanf("%d%d%d%d",&N,&M,&S,&T); update(); for(i=1;i<=M;i++){ scanf("%d%d%d",&u,&v,&w); add(u,v,w*(M+1)+1); } while(dis[S]<N) ans+=sap(S,inf); printf("%d ",ans%(M+1)); } return 0; }