独立博客: 哲学与程序

哲学与程序

判断最小割是否唯一 ZOJ@2587

ZOJ@2587
题意:判断最小割是否唯一。
思路(转):判断最小割是否唯一,先求一次最大流,然后在残留网络中分别从源汇开始dfs一次,找出最小割[S,T],如果SUT不包含所有点,那么最小割不唯一。假设点i不被SUT包含,那么残留网络中s不能到达i,i不能到达t,即进入i的边和从i出去的边都满流,假设某条进入i的边x满流,这些流量从若干条边y流出i,那么,如果选x为割边,或者选所有对应的y为割边,不会影响最大流,即最小割容量不变,最小割也就不唯一。
// 2390377      2011-01-21 16:52:22        Accepted      2587      C++      150      3324      redsea
//  Dinic最大流 O(V^2 * E) 
#include<cstdio>
#include
<algorithm>
#include
<cstring>
using namespace std;
#define N 802
#define E 200050
#define typec int                   // type of cost 
const typec inf = 30000000;       // max of cost 
struct edge { 
    
int x, y, nxt; typec c;
}bf[E]; 
int ne, head[N], cur[N], ps[N], dep[N]; 

void addedge(int x, int y, typec c) 
{  
    
// add an arc(x -> y, c); vertex: 0 ~ n-1; 
      bf[ne].x = x; bf[ne].y = y; bf[ne].c = c; 
      bf[ne].nxt 
= head[x]; head[x] = ne++
      bf[ne].x 
= y; bf[ne].y = x; bf[ne].c = 0
      bf[ne].nxt 
= head[y]; head[y] = ne++

typec flow(
int n, int s, int t) 

      typec tr, res 
= 0;
    
int i, j, k, f, r, top; 
    
while (1) { 
        memset(dep, 
-1, n * sizeof(int)); 
           
for (f = dep[ps[0= s] = 0, r = 1; f != r; ) 
            
for (i = ps[f++], j = head[i]; j; j = bf[j].nxt) 
            { 
                 
if (bf[j].c && -1 == dep[k = bf[j].y]){ 
                      dep[k] 
= dep[i] + 1; ps[r++= k; 
                      
if (k == t) { f = r; break; } 
                } 
               } 
        
if (-1 == dep[t]) break
        memcpy(cur, head, n 
* sizeof(int)); 
        
for (i = s, top = 0; ; ) { 
            
if (i == t) { 
                
for (k = 0, tr = inf; k < top; ++k) 
                     
if (bf[ps[k]].c < tr) 
                        tr 
= bf[ps[f = k]].c; 
                
for (k = 0; k < top; ++k) 
                    bf[ps[k]].c 
-= tr, bf[ps[k]^1].c += tr; 
                   res 
+= tr;  i = bf[ps[top = f]].x; 
            } 
            
for  (j=cur[i]; cur[i]; j = cur[i] = bf[cur[i]].nxt) 
                   
if  (bf[j].c && dep[i]+1 == dep[bf[j].y])break
            
if (cur[i]) { 
                   ps[top
++= cur[i]; 
                   i 
= bf[cur[i]].y; 
               } 
               
else { 
                 
if (0 == top) break
                   dep[i] 
= -1; i = bf[ps[--top]].x; 
               } 
           } 
    } 
    
return res; 
}
int cnts, cntt;
int flag1[N], flag2[N];

void dfs1(int v)
{
    flag1[v] 
= 1;
    cnts
++;
    
for(int i = head[v]; i != 0; i = bf[i].nxt){
        
if(flag1[bf[i].y]==0 && bf[i].c)
            dfs1(bf[i].y);
    }
}
void dfs2(int v)
{
    flag2[v] 
= 1;
    cntt
++;
    
for(int i = head[v]; i != 0; i = bf[i].nxt){
        
if(flag2[bf[i].y]==0 && bf[i^1].c)
            dfs2(bf[i].y);
    }
}
int main()
{
    
int n, m, s, t, x, y, c;
    
while(scanf("%d%d%d%d",&n,&m,&s,&t), n||m||s||t)
    {
        memset(head,
0,sizeof(head));
        ne 
= 2;
        
for(int i = 0; i < m; i++){
            scanf(
"%d%d%d",&x,&y,&c);
            x
--,y--;
            addedge(x,y,c);
            addedge(y,x,c);
        }
        s
--;t--;
        flow(n,s,t);
        memset(flag1,
0,sizeof(flag1));
        memset(flag2,
0,sizeof(flag2));
        cnts 
= cntt = 0;
        dfs1(s);
        dfs2(t);
        
if(cnts+cntt!=n)
            printf(
"AMBIGUOUS\n");
        
else printf("UNIQUE\n");
    }
    
return 0;
}


posted on 2011-01-21 17:11 哲学与程序 阅读(780) 评论(0)  编辑 收藏 引用 所属分类: Algorithm


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


导航

公告

欢迎访问 http://zhexue.sinaapp.com

常用链接

随笔分类(37)

随笔档案(41)

Algorithm

最新随笔

搜索

最新评论

独立博客: 哲学与程序