POJ1815 Friendship(字典序最小最小割割边集)

看了题解。当时也觉得用邻接矩阵挺好写的,直接memset;然而邻接矩阵不懂得改,于是就放开那个模板,写了Dinic。。

方法是,按字典序枚举每一条满流的边,然后令其容量减1,如果最大流改变了,这条边就是属于某个最小割;接下来一直重复下去,直到得到一个割边集,而它自然是字典序最小的。

我在每次某条边容量减1后都重新计算一遍最大流,简单。。其实我知道是有这么一回事,把边容量减1后可以利用当前求出的最大流来得出新的最大流,这样会快一些,不过我不会。。。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 #define INF (1<<30)
 6 int n,vs,vt,NV,c[444][444],f[444][444],level[444];
 7 bool bfs(){
 8     memset(level,0,sizeof(level));
 9     bool vis[444]={0};
10     vis[vs]=1;
11     int que[444],front=0,rear=0;
12     que[rear++]=vs;
13     while(front<rear){
14         int u=que[front++];
15         for(int v=1; v<=NV; ++v){
16             if(vis[v] || c[u][v]==f[u][v]) continue;
17             level[v]=level[u]+1;
18             vis[v]=1;
19             que[rear++]=v;
20         }
21         
22     }
23     return vis[vt+n];
24 }
25 int dfs(int u,int s){
26     if(u==vt+n) return s;
27     int res=s,tmp;
28     for(int v=1; v<=NV; ++v){
29         if(level[v]!=level[u]+1 || c[u][v]==f[u][v]) continue;
30         tmp=dfs(v,min(s,c[u][v]-f[u][v]));
31         f[u][v]+=tmp;
32         f[v][u]-=tmp;
33         s-=tmp;
34     }
35     return res-s;
36 }
37 int dinic(){
38     int res=0;
39     while(bfs()) res+=dfs(vs,INF);
40     return res;
41 }
42 int main(){
43     int a;
44     scanf("%d%d%d",&n,&vs,&vt);
45     NV=n<<1;
46     for(int i=1;i<=n;++i){
47         c[i][i+n]=1;
48         for(int j=1;j<=n;++j){
49             scanf("%d",&a);
50             if(i==j || a==0) continue;
51             c[i+n][j]=INF;
52         }
53     }
54     c[vs][vs+n]=INF; c[vt][vt+n]=INF;
55     if(c[vs+n][vt]){
56         puts("NO ANSWER!");
57         return 0;
58     }
59     int ans=dinic();
60     printf("%d\n",ans);
61     for(int i=1; i<=n&&ans; ++i){
62         if(i==vs||i==vt || f[i][i+n]==0) continue;
63         memset(f,0,sizeof(f));
64         c[i][i+n]=0;
65         if(dinic()<ans){
66             --ans;
67             printf("%d ",i);
68         }else{
69             c[i][i+n]=1;
70         }
71     }
72     return 0;
73 }

 

posted @ 2015-10-02 16:24  WABoss  阅读(677)  评论(0编辑  收藏  举报