zoj 2587 判断最小割的唯一性
算法:
先求出残量网络,计算出从src能够到的点集A,再求出能够到dst的点集B,如果所有点都被访问到了,那么割就是唯一的,即(A,B),否则(A,V-A)和(V-B,B)都是最小割。
(注意因为割的本质是有向边集,而不是点集V的划分,所以(A,V-A)和(V-B,B)有可能本质上还是同一个最小割,比如随便再加一个孤立点,虽然割还是唯一的,但还是有点没有被访问到,所以我们限制原图中所有点要么可以从src到达,要么可以到达dst)
1 #include <cstdio> 2 #include <cstring> 3 #include <vector> 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> edge; 14 vector<int> 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<g[u].size(); t++ ) { 36 Edge &e = edge[g[u][t]]; 37 if( e.f && !dep[e.v] ) { 38 dep[e.v] = dep[e.u]+1; 39 qu[++ed] = e.v; 40 } 41 } 42 } 43 return dep[dst]; 44 } 45 int dfs( int u, int a ) { 46 if( u==dst || a==0 ) return a; 47 int remain=a, past=0, na; 48 for( int &t=cur[u]; t<g[u].size(); t++ ) { 49 Edge &e=edge[g[u][t]]; 50 Edge &ve=edge[g[u][t]^1]; 51 if( e.f && dep[e.v]==dep[e.u]+1 && (na=dfs(e.v,min(remain,e.f))) ) { 52 remain -= na; 53 past += na; 54 e.f -= na; 55 ve.f += na; 56 if( !remain ) break; 57 } 58 } 59 return past; 60 } 61 int maxflow() { 62 int flow = 0; 63 while( bfs() ) { 64 memset( cur, 0, sizeof(cur) ); 65 flow += dfs(src,oo); 66 } 67 return flow; 68 } 69 bool check() { 70 int cnt = 0; 71 memset( vis, 0, sizeof(vis) ); 72 qu[bg=ed=1] = src; 73 vis[src] = true; 74 cnt++; 75 while( bg<=ed ) { 76 int u=qu[bg++]; 77 for( int t=0; t<g[u].size(); t++ ) { 78 Edge &e = edge[g[u][t]]; 79 if( e.f && !vis[e.v] ) { 80 qu[++ed] = e.v; 81 vis[e.v] = true; 82 cnt++; 83 } 84 } 85 } 86 qu[bg=ed=1] = dst; 87 vis[dst] = true; 88 cnt++; 89 while( bg<=ed ) { 90 int u=qu[bg++]; 91 for( int t=0; t<g[u].size(); t++ ) { 92 Edge &e = edge[g[u][t]^1]; 93 if( e.f && !vis[e.u] ) { 94 qu[++ed] = e.u; 95 vis[e.u] = true; 96 cnt++; 97 } 98 } 99 } 100 return n==cnt; 101 } 102 int main() { 103 while(1) { 104 scanf( "%d%d%d%d", &n, &m, &src, &dst ); 105 if( n==0 && m==0 && src==0 && dst==0 ) return 0; 106 init(n); 107 for( int i=1,u,v,f; i<=m; i++ ) { 108 scanf( "%d%d%d", &u, &v, &f ); 109 adde( u, v, f ); 110 adde( v, u, f ); 111 } 112 maxflow(); 113 printf( "%s\n", check() ? "UNIQUE" : "AMBIGUOUS" ); 114 } 115 }