zoukankan      html  css  js  c++  java
  • 【LA11248 训练指南】网络扩容【最大流】

    题意:

      给定一个有向网络,每条边均有一个容量。问是否存在一个从点1到点N,流量为C的流。如果不存在,是否可以恰好修改一条弧的容量,使得存在这样的流?

    分析:

      先跑一遍最大流,如果最大流大于等于C,则输possible。如果最大流小于C,则表明需要修改边的流量。很显然,需要修改的弧一定是满流的弧。但是如果直接暴力会超时,所以我们可以有两个优化。

     1.第一次求完最大流以后,把每条弧的流量保存下来,每次修改完一条弧的容量以后,都从当前残量网络开始继续增广。

     2.每次不需要增广到最大流,当流量大于等于C的时候就停止增广(不过不加这个优化好像也没事,反正我没加··)

      

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <algorithm>
      4 #include <iostream>
      5 #include <queue>
      6 #include <vector>
      7 
      8 using namespace std;
      9 const int maxn=100+10;
     10 const int maxm=20000+10;
     11 const int INF=2147000000;
     12 struct Dinic{
     13     int head[maxn],Next[maxm],to[maxm],from[maxm],cap[maxm],flow[maxm];
     14     int n,m,s,t,sz;
     15     bool vis[maxn];
     16     int d[maxn],cur[maxn];
     17     void init(int n){
     18         this->n=n;
     19         sz=-1;
     20         memset(head,-1,sizeof(head));
     21     }
     22     void add_edge(int a,int b,int c){
     23         ++sz;
     24         to[sz]=b;Next[sz]=head[a];head[a]=sz;
     25         cap[sz]=c;flow[sz]=0,from[sz]=a;;
     26         ++sz;
     27         to[sz]=a;Next[sz]=head[b];head[b]=sz;
     28         cap[sz]=c;flow[sz]=c,from[sz]=b;
     29     }
     30     bool BFS(){
     31         memset(vis,0,sizeof(vis));
     32         for(int i=0;i<=n;i++)d[i]=INF;
     33         queue<int>Q;
     34         d[s]=0,vis[s]=1;
     35         Q.push(s);
     36         while(!Q.empty()){
     37             int u=Q.front();Q.pop();
     38             for(int i=head[u];i!=-1;i=Next[i]){
     39                 int v=to[i];
     40                 if(cap[i]>flow[i]&&!vis[v]){
     41                     vis[v]=1;
     42                     d[v]=d[u]+1;
     43                     Q.push(v);
     44                 }
     45             }
     46         }
     47         return vis[t];
     48     }
     49     int DFS(int x,int a){
     50         if(x==t||a==0)return a;
     51         int Flow=0,f;
     52         for(int& i=cur[x];i!=-1;i=Next[i]){
     53             int v=to[i];
     54             if(d[v]==d[x]+1&&(f=DFS(v,min(a,cap[i]-flow[i])))>0){
     55                 Flow+=f;
     56                 flow[i]+=f;
     57                 flow[i^1]-=f;
     58                 a-=f;
     59                 if(a==0)break;
     60             }
     61         }
     62         return Flow;
     63     }
     64     int Maxflow(int s,int t){
     65         this->s=s;this->t=t;
     66         int Flow=0;
     67         while(BFS()){
     68             for(int i=0;i<=n;i++)cur[i]=head[i];
     69             Flow+=DFS(s,INF);
     70         }
     71         return Flow;
     72     }
     73 }dinic;
     74 struct Edge{
     75     int from,to;
     76     bool operator <(const Edge& rhs)const{
     77         return from<rhs.from||(from==rhs.from&&to<rhs.to);
     78     }
     79 };
     80 vector<Edge>ans;
     81 int kase,N,E,C;
     82 int main(){
     83     kase=0;
     84     while(scanf("%d%d%d",&N,&E,&C)!=EOF&&(N||E||C)){
     85         ++kase;
     86         printf("Case %d: ",kase);
     87         ans.clear();
     88         dinic.init(N);
     89         int u,v,c;
     90         for(int i=1;i<=E;i++){
     91             scanf("%d%d%d",&u,&v,&c);
     92             dinic.add_edge(u,v,c);
     93         }
     94         int Maxflow=dinic.Maxflow(1,N);
     95         if(Maxflow>=C){
     96             printf("possible
    ");
     97         }else{
     98             int FLOW[maxm];
     99             for(int i=0;i<=dinic.sz;i++){
    100                 FLOW[i]=dinic.flow[i];
    101             }
    102             int CAP,c=C-Maxflow;
    103             for(int i=0;i<=dinic.sz;i+=2){
    104                 if(dinic.cap[i]==dinic.flow[i]){
    105 
    106                     for(int i=0;i<=dinic.sz;i++)dinic.flow[i]=FLOW[i];
    107                     CAP=dinic.cap[i];
    108                     dinic.cap[i]=C;
    109                     dinic.cap[i^1]=C;
    110                     Maxflow=dinic.Maxflow(1,N);
    111                     if(Maxflow>=c){
    112                         ans.push_back((Edge){dinic.from[i],dinic.to[i]});
    113                     }
    114                     dinic.cap[i]=CAP;
    115                     dinic.cap[i^1]=CAP;
    116                     for(int i=0;i<=dinic.sz;i++)dinic.flow[i]=FLOW[i];
    117                 }
    118             }
    119             if(ans.size()==0){
    120                 printf("not possible
    ");
    121             }else{
    122                 sort(ans.begin(),ans.end());
    123                 printf("possible option:");
    124                 for(int i=0;i<ans.size();i++){
    125                     if(i!=0)printf(",");
    126                     printf("(%d,%d)",ans[i].from,ans[i].to);
    127                 }
    128                 printf("
    ");
    129             }
    130         }
    131     }
    132 return 0;
    133 }
    View Code
  • 相关阅读:
    100多个淘宝抢的双11红包怎么用?最多才能累积使用15个
    灵动标签调用友情链接
    台湾短片:《血战古.宁.头》
    discuz_style_default.xml 修改
    discuz门户文章页面模板修改
    ps快捷键
    拍摄好的图片,如何抠图去背景纯白..
    Centos6.5安装rabbmitmq蛋碎
    好用的YUM源
    python_函数的参数
  • 原文地址:https://www.cnblogs.com/LQLlulu/p/9303479.html
Copyright © 2011-2022 走看看