UVa 11248 网络扩容(最大流(需要优化))

Posted 谦谦君子,陌上其华

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVa 11248 网络扩容(最大流(需要优化))相关的知识,希望对你有一定的参考价值。

https://vjudge.net/problem/UVA-11248

题意:

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

 

思路:

先求一遍最大流,如果大于等于C,那么就直接输出possible。

否则的话就是最大流达不到C,那么对哪些边进行扩容呢,肯定是选择最小割!

将最小割的边集全部求出来,之后每条边都尝试将容量变为C,看看能否达到要求。

优化一:求完最大流后把流量留着,以后每次在它的基础上增广。

优化二:每次没必要求出最大流,增广到流量至少为C时就可以停下来。

  1 #include<iostream>
  2 #include<algorithm>
  3 #include<cstring>
  4 #include<cstdio>
  5 #include<vector>
  6 #include<queue>
  7 #include<cmath>
  8 #include<map>
  9 using namespace std;
 10 
 11 const int maxn=100+5;
 12 const int INF=0x3f3f3f3f;
 13 
 14 struct Edge
 15 {
 16     int from,to,cap,flow;
 17     Edge(int u,int v,int w,int f):from(u),to(v),cap(w),flow(f){}
 18 };
 19 
 20 struct Dinic
 21 {
 22     int n,m,s,t;
 23     vector<Edge> edges;
 24     vector<int> G[maxn];
 25     bool vis[maxn];
 26     int cur[maxn];
 27     int d[maxn];
 28 
 29     void init(int n)
 30     {
 31         this->n=n;
 32         for(int i=0;i<n;++i) G[i].clear();
 33         edges.clear();
 34     }
 35 
 36     void AddEdge(int from,int to,int cap)
 37     {
 38         edges.push_back( Edge(from,to,cap,0) );
 39         edges.push_back( Edge(to,from,0,0) );
 40         m=edges.size();
 41         G[from].push_back(m-2);
 42         G[to].push_back(m-1);
 43     }
 44 
 45     bool BFS()
 46     {
 47         queue<int> Q;
 48         memset(vis,0,sizeof(vis));
 49         vis[s]=true;
 50         d[s]=0;
 51         Q.push(s);
 52         while(!Q.empty())
 53         {
 54             int x=Q.front(); Q.pop();
 55             for(int i=0;i<G[x].size();++i)
 56             {
 57                 Edge& e=edges[G[x][i]];
 58                 if(!vis[e.to] && e.cap>e.flow)
 59                 {
 60                     vis[e.to]=true;
 61                     d[e.to]=d[x]+1;
 62                     Q.push(e.to);
 63                 }
 64             }
 65         }
 66         return vis[t];
 67     }
 68 
 69     int DFS(int x,int a)
 70     {
 71         if(x==t || a==0) return a;
 72         int flow=0, f;
 73         for(int &i=cur[x];i<G[x].size();++i)
 74         {
 75             Edge &e=edges[G[x][i]];
 76             if(d[e.to]==d[x]+1 && (f=DFS(e.to,min(a,e.cap-e.flow) ) )>0)
 77             {
 78                 e.flow +=f;
 79                 edges[G[x][i]^1].flow -=f;
 80                 flow +=f;
 81                 a -=f;
 82                 if(a==0) break;
 83             }
 84         }
 85         return flow;
 86     }
 87 
 88     int Maxflow(int s,int t,int need)
 89     {
 90         this->s=s; this->t=t;
 91         int flow=0;
 92         while(BFS())
 93         {
 94             memset(cur,0,sizeof(cur));
 95             flow +=DFS(s,INF);
 96             if(flow>=need)  return flow;
 97         }
 98         return flow;
 99     }
100 
101     //最小割的边集
102     vector<int> Mincut()
103     {
104         BFS();
105         vector<int> ans;
106         for(int i=0;i<edges.size();i++)
107         {
108             Edge& e=edges[i];
109             if(vis[e.from] && !vis[e.to] && e.cap>0)  ans.push_back(i);
110         }
111         return ans;
112     }
113 
114     void Reduce()
115     {
116         for(int i=0;i<edges.size();i++)
117         {
118             Edge& e=edges[i];
119             e.cap-=e.flow;
120         }
121     }
122 
123     void Clearflow()
124     {
125         for(int i=0;i<edges.size();i++)
126         {
127             Edge& e=edges[i];
128             e.flow=0;
129         }
130     };
131 
132 }DC;
133 
134 int n,e,c;
135 
136 bool cmp(Edge a,Edge b)
137 {
138     return a.from<b.from||((a.from==b.from)&&(a.to<b.to));
139 }
140 
141 int main()
142 {
143     //freopen("D:\\input.txt","r",stdin);
144     int kase=0;
145     while(~scanf("%d%d%d",&n,&e,&c))
146     {
147         if(!n) break;
148         DC.init(n+1);
149         int u,v,w;
150         for(int i=0;i<e;i++)
151         {
152             scanf("%d%d%d",&u,&v,&w);
153             DC.AddEdge(u,v,w);
154         }
155         printf("Case %d: ",++kase);
156         int ans=DC.Maxflow(1,n,INF);
157         if(ans>=c)
158         {
159             printf("possible\n");
160             continue;
161         }
162         vector<int> cut=DC.Mincut();
163         DC.Reduce();
164         vector<Edge> change;
165         for(int i=0;i<cut.size();i++)
166         {
167             DC.Clearflow();
168             Edge& e=DC.edges[cut[i]];
169             int temp=e.cap;
170             e.cap=c;
171             if(DC.Maxflow(1,n,c-ans)>=c-ans)  change.push_back(e);
172             e.cap=temp;
173         }
174         if(change.empty())
175         {
176             printf("not possible\n");
177             continue;
178         }
179         sort(change.begin(),change.end(),cmp);
180         printf("possible option:");
181         printf("(%d,%d)",change[0].from,change[0].to);
182         for(int i=1;i<change.size();i++)
183             printf(",(%d,%d)",change[i].from,change[i].to);
184         printf("\n");
185     }
186 }

 

以上是关于UVa 11248 网络扩容(最大流(需要优化))的主要内容,如果未能解决你的问题,请参考以下文章

UVa 11248 Frequency Hopping (网络流)

训练指南 网络流题集

BZOJ1834网络扩容(最大流,费用流)

[ZJOI2010]网络扩容 (最大流 + 费用流)

Uva 10480 Sabotage 最大流

uva 753(网络流最大流)