zoukankan      html  css  js  c++  java
  • 奶牛通讯 usaco 网络流

    这道题很有意思,原题是只需输出最小割集大小,现在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
  • 相关阅读:
    使用环信WebIm实现一个客服功能
    html中的下拉框—select和input方式
    [LeetCode] 206. Reverse Linked List
    visual studio 2019安装配置可编写c/c++语言的IDE环境
    JS判断数据类型是不是undefined
    idea微服务架构出现 Run Dashboard 按钮方法
    docker 常用命令
    配置docker镜像加速
    linux安装docker
    linux安装redis
  • 原文地址:https://www.cnblogs.com/chadinblog/p/5860438.html
Copyright © 2011-2022 走看看