算法:
先求出残量网络,计算出从src能够到的点集A,再求出能够到dst的点集B,如果所有点都被访问到了,那么割就是唯一的,即(A,B),否则(A,V-A)和(V-B,B)都是最小割。
(注意因为割的本质是有向边集,而不是点集V的划分,所以(A,V-A)和(V-B,B)有可能本质上还是同一个最小割,比如随便再加一个孤立点,虽然割还是唯一的,但还是有点没有被访问到,所以我们限制原图中所有点要么可以从src到达,要么可以到达dst)
1 #include2 #include 3 #include 4 #define N 810 5 #define oo 0x3f3f3f3f 6 using namespace std; 7 8 struct Edge { 9 int u, v, f; 10 Edge( int u, int v, int f ):u(u),v(v),f(f){} 11 }; 12 int n, m, src, dst; 13 vector edge; 14 vector g[N]; 15 int dep[N], cur[N], qu[N], bg, ed; 16 bool vis[N]; 17 18 void init( int n ) { 19 edge.clear(); 20 for( int u=1; u<=n; u++ ) 21 g[u].clear(); 22 } 23 void adde( int u, int v, int f ) { 24 g[u].push_back( edge.size() ); 25 edge.push_back( Edge(u,v,f) ); 26 g[v].push_back( edge.size() ); 27 edge.push_back( Edge(v,u,0) ); 28 } 29 bool bfs() { 30 memset( dep, 0, sizeof(dep) ); 31 qu[bg=ed=1] = src; 32 dep[src] = 1; 33 while( bg<=ed ) { 34 int u=qu[bg++]; 35 for( int t=0; t