poj 1815 最小点割转化为最小边割+枚举 (邻接矩阵+递归dinic)
2012-09-22 21:16
375 查看
题意就是去掉几个点,是VS与VT不连通。并问去掉了哪几个点?。
本来是最小点割的,但要转化成最小边割,就是拆点,把点变成边就行了。容量为1 。其他点相连时权值为MX。
求一次最大流,若为MX,那么就证明VS与VT直接相连了,NO ANSWER!
若不为MX,那么从第一个点枚举,去掉这个点,即i到i+n边容量从1边为0 。初始流量。求次最大流看看流量改没改变,若改变了,那么就说明此点是我们要找的。但不要把边权值改回去。
若未改变,那么把边改回去。
本来是最小点割的,但要转化成最小边割,就是拆点,把点变成边就行了。容量为1 。其他点相连时权值为MX。
求一次最大流,若为MX,那么就证明VS与VT直接相连了,NO ANSWER!
若不为MX,那么从第一个点枚举,去掉这个点,即i到i+n边容量从1边为0 。初始流量。求次最大流看看流量改没改变,若改变了,那么就说明此点是我们要找的。但不要把边权值改回去。
若未改变,那么把边改回去。
#include<stdio.h> #include<string.h> #define MX 10000 struct Edge{ int f,c; }eg[1000][1000]; int n,vs,vt,dist[1000],que[10000],map[500][500]; int min(int a,int b){ return a<b?a:b; } bool bfs(){ int qs=0,qe=1; que[0]=vs; memset(dist,-1,sizeof(dist)); dist[vs]=0; while(qs<qe){ int v=que[qs++]; for(int i=1;i<=2*n;i++){ if(eg[v][i].c-eg[v][i].f&&dist[i]==-1){ que[qe++]=i; dist[i]=dist[v]+1; if(dist[vt]!=-1){ return true; } } } } return false; } int dfs(int sta,int sum){ if(sta==vt){ return sum; } int sumcy=sum; for(int i=1;i<=2*n;i++){ if(eg[sta][i].c-eg[sta][i].f&&dist[i]==dist[sta]+1){ int t=dfs(i,min(sum,eg[sta][i].c-eg[sta][i].f)); sum-=t; eg[sta][i].f+=t; eg[i][sta].f-=t; } } return sumcy-sum; } int dinic(){ int ans=0; while(bfs()){ ans+=dfs(vs,MX); } return ans; } int main(){ while(scanf("%d%d%d",&n,&vs,&vt)!=EOF){ memset(eg,0,sizeof(eg)); for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ scanf("%d",&map[i][j]); eg[i][n+i].c=1; if(map[i][j]){ eg[i+n][j].c=MX; } } } eg[vs][vs+n].c=MX; eg[vt][vt+n].c=MX; int ans=dinic(); if(ans==MX){ printf("NO ANSWER!\n"); continue; } printf("%d\n",ans); int pos=0,it[1000]; for(int i=1;i<=2*n;i++){ if(i==vt||i==vs||eg[i][i+n].f==0){ continue; } eg[i][i+n].c=0; for(int k=1;k<=n*2;k++){ for(int j=1;j<=2*n;j++){ eg[k][j].f=0; } } if(ans!=dinic()){ it[pos++]=i; ans--; } else{ eg[i][i+n].c=1; } } for(int i=0;i<pos-1;i++){ printf("%d ",it[i]); } if(pos) printf("%d\n",it[pos-1]); } return 0; }
相关文章推荐
- poj 1815 Friendship 【最小割点集】【枚举删点 + 求解最小字典序】
- Friendship (poj 1815 最小点割集+枚举)
- poj 1815(最小割 + 枚举)
- POJ 1815 求最小点割(拆点+枚举割边)
- poj 1815(最小割+枚举)
- Poj 1815 Friendship 枚举+求最小割
- poj 1815 Friendship (最小割+拆点+枚举)
- POJ 1815 最小割 拆点 枚举
- [最小点割集]poj 1815 #贪心枚举
- poj--1815--Friendship(最小割点集)(枚举求最小字典序)
- poj 1815 Friendship (最小割+拆点+枚举)
- POJ 1815 最大流最小割枚举找割点
- POJ 1815 - Friendship 求最小割点..要求字典序...枚举+最小割
- 【最小割+枚举】POJ-1815 Friendship
- POJ 1966--Cable TV Network【最小割 && 枚举终点起点】
- POJ 2784 Buy or Build(二进制枚举 + 最小生成树)
- POJ 1815 Friendship(字典序最小最小割)
- POJ 1815 Friendship(最小割)
- POJ 1815 (最小割的点集)
- POJ 1815 Friendship(最小割+字典序输出割点)