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

奶牛通讯 usaco 网络流

时间:2016-09-11 00:05:56      阅读:264      评论:0      收藏:0      [点我收藏+]

标签:

这道题很有意思,原题是只需输出最小割集大小,现在oj上改成了输出字典序最小的割集;

题解:可以考虑从小到大删边,若删掉这条边后,最小割变小,保持不变,记录此时的最小割大小;

若最小割不变,恢复这条边;

这样做的原因是什么呢?从小到大可以保证字典序的要求,删完边后若最小割减小,这条边一定在最小割上,删掉它不再恢复可以保证不在把这条通路上的其他边也收进来;

网络流博大精深,还是需要好好体会的;

但在此之前,应该先会敲代码;

技术分享
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<string>
 5 #include<cstdlib>
 6 #include<ctime>
 7 #include<algorithm>
 8 using namespace std;
 9 const int maxn=400;
10 const int inf=1000000000;
11 int S,T,n,m;
12 struct node{
13     int y,next,re,flow;
14 }e[maxn<<4],e2[maxn<<4];
15 int linkk[maxn],len=0;
16 void insert(int x,int y,int flow){
17     e[++len].y=y;
18     e[len].next=linkk[x];
19     linkk[x]=len;
20     e[len].flow=flow;
21     e[len].re=len+1;
22     e[++len].y=x;
23     e[len].next=linkk[y];
24     linkk[y]=len;
25     e[len].flow=0;
26     e[len].re=len-1;
27 }
28 void init(){
29     scanf("%d%d%d%d",&n,&m,&S,&T);
30     int x,y;
31     for(int i=1;i<=m;i++){
32         scanf("%d%d",&x,&y);
33         if(x==S){insert(S,y,inf);insert(y+n,S,inf);}
34         else if(y==S){insert(S,x,inf);insert(x+n,S,inf);}
35         else if(x==T){insert(T,y,inf);insert(y+n,T,inf);}
36         else if(y==T){insert(x+n,T,inf);insert(T,x,inf);}
37         else {insert(x+n,y,inf);insert(y+n,x,inf);}
38     }
39     for(int i=1;i<=n;i++)if(S!=i&&T!=i)insert(i,i+n,1);
40 }
41 bool flag=1;
42 int flow=inf,vis[maxn],ans=0,f[maxn];
43 void dfs(int x,int a){
44     if(f[x])return;
45     vis[x]=1;
46     if(x==T){
47         flag=1;flow=a;ans+=flow;return;
48     }
49     for(int i=linkk[x];i;i=e[i].next){
50         if(vis[e[i].y]||(!e[i].flow))continue;
51         dfs(e[i].y,min(a,e[i].flow));
52         if(flag){
53             e[i].flow-=flow;e[e[i].re].flow+=flow;return;
54         }
55     }
56 }
57 void work(){
58     ans=0;flag=1;
59     while(flag){
60         flag=0;
61         memset(vis,0,sizeof(vis));
62         dfs(S,inf);
63     }
64 }
65 int main(){
66     freopen("1.in","r",stdin);
67     freopen("1.out","w",stdout);
68     init();
69     memcpy(e2,e,sizeof(e));
70     work();
71     cout<<ans<<endl;
72     int q[maxn],sum=ans,k=ans,tail=0;
73     for(int i=1;i<=n;i++){
74         if(i==S||i==T)continue;
75         memcpy(e,e2,sizeof(e));
76         f[i]=1;
77         work();
78         if(ans<sum)q[++tail]=i,sum=ans;
79         else f[i]=0;
80     }
81     sort(q+1,q+tail+1);
82     for(int i=1;i<=k;i++)printf("%d ",q[i]);
83 }
View Code

 

奶牛通讯 usaco 网络流

标签:

原文地址:http://www.cnblogs.com/chadinblog/p/5860438.html

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