ZOJ 2532 Internship
2010-12-29 20:49
507 查看
找关键割边,即如果只是增加这条的边容量后,能增加最大流,那么,这条边满足3条性质:
1.满流,如果不满流,增大容量也没用
2.残余网络中,源点可以到达该边的头节点
3.残余网络中,该边的尾节点可以到达汇点
即通过这条扩容的边后可以重新找到一条增广路径
做法跟POJ 3204相同,先跑一次最大流,然后分别从源点和汇点开始,在残余网络中做两次DFS
但这道题按从小到大的顺序需要输出关键割边在输入数据中的id,即第几天边,我一开始用一个数组记录的,但最后WA了,用了别人的方法,现在网络中增加segment边,这样,第i条segment边在数组中的下标就为(i-1)*2,这样就过了,所以数据中应该有重边
代码:
1.满流,如果不满流,增大容量也没用
2.残余网络中,源点可以到达该边的头节点
3.残余网络中,该边的尾节点可以到达汇点
即通过这条扩容的边后可以重新找到一条增广路径
做法跟POJ 3204相同,先跑一次最大流,然后分别从源点和汇点开始,在残余网络中做两次DFS
但这道题按从小到大的顺序需要输出关键割边在输入数据中的id,即第几天边,我一开始用一个数组记录的,但最后WA了,用了别人的方法,现在网络中增加segment边,这样,第i条segment边在数组中的下标就为(i-1)*2,这样就过了,所以数据中应该有重边
代码:
#include<iostream> #include<algorithm> #include<stdio.h> #include<memory.h> using namespace std; const int MAX=105; const int inf=1<<30; struct node { int u,v,c,next; }g[10000]; int dis[MAX],cur[MAX],num[MAX],adj[MAX],pre[MAX]; int edge[MAX][MAX],res[MAX],vs[MAX],vt[MAX]; int s,t,vn,e; void add(int u,int v,int c) { g[e].u=u; g[e].v=v; g[e].c=c; g[e].next=adj[u]; adj[u]=e++; g[e].u=v; g[e].v=u; g[e].c=0; g[e].next=adj[v]; adj[v]=e++; } void dfs1(int x) { vs[x]=1; for(int i=adj[x];i!=-1;i=g[i].next) { if(g[i].c&&!vs[g[i].v]) dfs1(g[i].v); } } void dfs2(int x)//从汇点开始反向DFS { vt[x]=1; for(int i=adj[x];i!=-1;i=g[i].next) { if(g[i^1].c&&!vt[g[i].v])//i^1为i的反向边,找能从g[i].v->x的边 dfs2(g[i].v); } } int sap() { int i,u,v,flow=0,aug=inf,flag; for(i=0;i<=vn;i++) { dis[i]=num[i]=0; cur[i]=adj[i]; } pre[s]=u=s; num[0]=vn; while(dis[s]<vn) { flag=0; for(i=cur[u];i!=-1;i=g[i].next) { v=g[i].v; if(g[i].c&&dis[u]==dis[v]+1) { flag=1; pre[v]=u; cur[u]=i; aug=min(aug,g[i].c); u=v; if(u==t) { flow+=aug; while(u!=s) { u=pre[u]; g[cur[u]].c-=aug; g[cur[u]^1].c+=aug; } aug=inf; } break; } } if(flag) continue; if(--num[dis[u]]==0) break; for(dis[u]=vn,i=adj[u];i!=-1;i=g[i].next) { v=g[i].v; if(g[i].c&&dis[v]<dis[u]) { dis[u]=dis[v]; cur[u]=i; } } dis[u]++; num[dis[u]]++; u=pre[u]; } return flow; } int main() { int i,m,n,l,a,b,w,cnt; while(scanf("%d%d%d",&n,&m,&l)!=EOF) { if(!n) break; memset(adj,-1,sizeof(adj)); //memset(edge,0,sizeof(edge)); e=0; s=n+m+1; t=0; vn=s+1; for(i=1;i<=l;i++) { scanf("%d%d%d",&a,&b,&w); //edge[a][b]=edge[b][a]=i; add(a,b,w); } for(i=1;i<=n;i++) add(s,i,inf); sap(); memset(vs,0,sizeof(vs)); memset(vt,0,sizeof(vt)); dfs1(s); dfs2(t); //memset(res,0,sizeof(res)); cnt=0; for(i=0;i<e;i+=2) { if(g[i].c==0&&vs[g[i].u]&&vt[g[i].v]) { if(cnt==0) printf("%d",i/2+1); else printf(" %d",i/2+1); cnt++; //res[cnt++]=edge[g[i].u][g[i].v]; } } /*sort(res,res+cnt); for(i=0;i<cnt;i++) { if(i) printf(" %d",res[i]); else printf("%d",res[i]); }*/ if(!cnt) printf("/n"); printf("/n"); } return 0; }
相关文章推荐
- zoj 2532(Internship )找割边
- ZOJ 2532 Internship 最小割
- poj 3204 Ikki's Story I - Road Reconstruction && zoj 2532 Internship 网络流关键边
- ZOJ 2532 Internship
- 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
- ZOJ2532_Internship
- ZOJ 2532 Internship 网络流求关键边
- 【ZOJ】2532 Internship 最小割——关键割边
- zoj 2532 Internship【最小割】
- ZOJ 2532 Internship(最大流找关键割边)
- zoj 2532(最大流处理来求关键边)
- ZOJ2532-网络流求关键边
- zoj 2532(网络流)
- 【最大流|关键边】ZOJ-1532 Internship
- ZOJ 2532 最小割