ZOJ 2532 Internship
2017-10-22 20:57
405 查看
ZOJ 2532 Internship
网络流题意
CIA公司想采用新技术升级网络,在实验测试阶段,他们想升级其中的一段网络以便观察新技术在多大的长度上提升网络的性能,你作为实习生的任务是调查那一段网络能提高CIA总部的宽带。思路
找割边集。判断一段网络可不可以提升网络就要看它是不是满流,如果满流则可能在升级后提升CIA总部的宽带,但是如果提升后并不能增广,即不能提升CIA总部的宽带,所以判断一段是不是可提升的则有两个条件:(1)在进行增广后这段网络是满流的,(2)在提升后可以增广。
所以从源DFS一次,标记,从汇DFS一次,标记。再枚举边,判断。
代码
ZOJ上不去,粘的别人的。#include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <queue> #include <stack> #include <map> #include <set> #include <vector> #include <algorithm> using namespace std; const int INF = 0x3f3f3f3f; typedef struct node { int u; int v; int Flow; int next; }Line; Line Li[2200]; int Head[110],top; int vis[110],ans[110]; bool vis1[110],vis2[110]; int n,m,l; int s,t; void AddEdge(int u,int v,int f) { Li[top].v=v; Li[top].u=u; Li[top].Flow=f; Li[top].next=Head[u]; Head[u]=top++; } bool BFS() { memset(vis,-1,sizeof(vis)); vis[s]=0; queue<int >Q; Q.push(s); while(!Q.empty()) { int u=Q.front(); Q.pop(); for(int i=Head[u];i!=-1;i=Li[i].next) { if(Li[i].Flow&&vis[Li[i].v]==-1) { vis[Li[i].v]=vis[u]+1; Q.push(Li[i].v); } } } return vis[t]!=-1; } int DFS(int u,int f) { if(u==t) { return f; } int ans=0; for(int i=Head[u];i!=-1;i=Li[i].next) { if(Li[i].Flow&&vis[Li[i].v]==vis[u]+1) { int d=DFS(Li[i].v,min(f,Li[i].Flow)); f-=d; Li[i].Flow-=d; Li[i^1].Flow+=d; ans+=d; } } return ans; } void dfs(int u,bool *vist,int op) { vist[u]=true; for(int i=Head[u];i!=-1;i=Li[i].next) { if(!vist[Li[i].v]&&Li[i^op].Flow!=0) { dfs(Li[i].v,vist,op); } } } void Dinic()//网络流进行增广 { int ans; while(BFS()) { ans=DFS(s,INF); } } int main() { while(~scanf("%d %d %d",&n,&m,&l)) { if(n+m+l==0) { break; } s=n+m+1;//源点 t=0;//汇点 memset(Head,-1,sizeof(Head)); int a,b,c; top = 0; for(int i=0;i<l;i++) { scanf("%d %d %d",&a,&b,&c); AddEdge(a,b,c);//建立边,正向为c,负向为0 AddEdge(b,a,0); } for(int i=1;i<=n;i++) { AddEdge(s,i,INF); AddEdge(i,s,0);//建立城市与源点之间的边,权值为INF } Dinic(); memset(vis1,false,sizeof(vis1)); memset(vis2,false,sizeof(vis2)); dfs(s,vis1,0);//从源点向汇点搜索,标记还有剩余流的点 dfs(t,vis2,1);//从汇点到源点搜索,标记还有剩余流的点 int num=0; for(int i=0;i<l;i++) { if(Li[i<<1].Flow==0&&vis1[Li[i<<1].u]&&vis2[Li[i<<1].v]) { ans[num++]=i+1;//如果一条边的u与v都被标记,表明s->u,v->t,但是这条边是满流,所以提升这条边。 } } if(num) { for(int i=0;i<num;i++) { if(i) { printf(" "); } printf("%d",ans[i]); } } printf("\n"); } return 0; }
相关文章推荐
- zoj 2532 Internship(最大流求割边)
- ZOJ2532_Internship
- ZOJ 2532 Internship(最大流找关键割边)
- ZOJ 2532 Internship 网络流求关键边
- zoj 2532(Internship )找割边
- 【ZOJ】2532 Internship 最小割——关键割边
- ZOJ 2532 Internship
- ZOJ 2532 Internship 最小割
- poj 3204 Ikki's Story I - Road Reconstruction && zoj 2532 Internship 网络流关键边
- poj 3204 Ikki's Story I - Road Reconstruction && zoj 2532 Internship 网络流关键边
- zoj 2532 Internship 找出关键割边(当增加其容量后使最大流增大) 最小割+dfs
- ZOJ 2532 Internship
- zoj 2532 Internship【最小割】
- ZOJ 2532 Internship
- ZOJ 2532 - Internship(网络流‘最小割)
- 【最大流|关键边】ZOJ-1532 Internship
- zoj 2532(最大流处理来求关键边)
- ZOJ2532-网络流求关键边
- ZOJ 2532 最小割
- zoj 2532(网络流)