码迷,mamicode.com
首页 > 其他好文 > 详细

zoj 2587 判断最小割的唯一性

时间:2015-05-26 18:03:34      阅读:181      评论:0      收藏:0      [点我收藏+]

标签:

 

算法:

  先求出残量网络,计算出从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 }
View Code

 

zoj 2587 判断最小割的唯一性

标签:

原文地址:http://www.cnblogs.com/idy002/p/4531011.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!