poj 2125(最小割)
来源:互联网 发布:mac php protobuf 编辑:程序博客网 时间:2024/05/18 01:22
题目链接:http://poj.org/problem?id=2125
思路:将最小点权覆盖转化为最小割模型,于是拆点建图,将点i拆成i,i+n,其中vs与i相连,边容量为w[i]-,i+n与vt相连,边容量为w[i]+,如果i,j有边相连,则i与j+n连边inf.从而跑最大流求解。对于输出解决放案,我们可以在残余网络中进行dfs,从vs出发,对于那些i<=n没有遍历到的点,说明被取走了,输出‘-’,对于那些i>n遍历到的点,说明之前有j->i的边(j<=n),vs->j不是最小割中的边,i是最小割中的点,输出‘+’。
copy一张图:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 using namespace std; 7 #define MAXN 222 8 #define MAXM 2222222 9 #define inf 1<<30 10 11 struct Edge{ 12 int v,cap,next; 13 }edge[MAXM]; 14 15 int n,m,NE,vs,vt,NV; 16 int head[MAXN]; 17 18 void Insert(int u,int v,int cap) 19 { 20 edge[NE].v=v; 21 edge[NE].cap=cap; 22 edge[NE].next=head[u]; 23 head[u]=NE++; 24 25 edge[NE].v=u; 26 edge[NE].cap=0; 27 edge[NE].next=head[v]; 28 head[v]=NE++; 29 } 30 31 int from[MAXN],to[MAXN]; 32 bool map[MAXN][MAXN]; 33 34 void Build() 35 { 36 NE=0; 37 memset(head,-1,sizeof(head)); 38 vs=0,vt=2*n+1,NV=2*n+2; 39 for(int i=1;i<=n;i++){ 40 Insert(vs,i,to[i]); 41 Insert(i+n,vt,from[i]); 42 for(int j=1;j<=n;j++){ 43 if(map[i][j])Insert(i,j+n,inf); 44 } 45 } 46 } 47 48 int level[MAXN],gap[MAXN]; 49 void bfs(int vt) 50 { 51 memset(level,-1,sizeof(level)); 52 memset(gap,0,sizeof(gap)); 53 level[vt]=0; 54 gap[level[vt]]++; 55 queue<int>que; 56 que.push(vt); 57 while(!que.empty()){ 58 int u=que.front(); 59 que.pop(); 60 for(int i=head[u];i!=-1;i=edge[i].next){ 61 int v=edge[i].v; 62 if(level[v]<0){ 63 level[v]=level[u]+1; 64 gap[level[v]]++; 65 que.push(v); 66 } 67 } 68 } 69 } 70 71 int cur[MAXN],pre[MAXN]; 72 73 int SAP(int vs,int vt) 74 { 75 bfs(vt); 76 memset(pre,-1,sizeof(pre)); 77 memcpy(cur,head,sizeof(head)); 78 int maxflow=0,aug=inf; 79 int u=pre[vs]=vs; 80 gap[0]=NV; 81 while(level[vs]<NV){ 82 bool flag=false; 83 for(int &i=cur[u];i!=-1;i=edge[i].next){ 84 int v=edge[i].v; 85 if(edge[i].cap>0&&level[u]==level[v]+1){ 86 flag=true; 87 pre[v]=u; 88 u=v; 89 aug=min(aug,edge[i].cap); 90 if(v==vt){ 91 maxflow+=aug; 92 for(u=pre[v];v!=vs;v=u,u=pre[u]){ 93 edge[cur[u]].cap-=aug; 94 edge[cur[u]^1].cap+=aug; 95 } 96 aug=inf; 97 } 98 break; 99 }100 }101 if(flag)continue;102 int minlevel=NV;103 for(int i=head[u];i!=-1;i=edge[i].next){104 int v=edge[i].v;105 if(edge[i].cap>0&&level[v]<minlevel){106 minlevel=level[v];107 cur[u]=i;108 }109 }110 if(--gap[level[u]]==0)break;111 level[u]=minlevel+1;112 gap[level[u]]++;113 u=pre[u];114 }115 return maxflow;116 }117 118 bool mark[MAXN];119 void dfs(int u)120 {121 mark[u]=true;122 for(int i=head[u];i!=-1;i=edge[i].next){123 int v=edge[i].v;124 if(!mark[v]&&edge[i].cap>0)dfs(v);125 }126 }127 128 129 int main()130 {131 // freopen("1.txt","r",stdin);132 int u,v,cnt;133 while(~scanf("%d%d",&n,&m)){134 for(int i=1;i<=n;i++)scanf("%d",&from[i]);135 for(int i=1;i<=n;i++)scanf("%d",&to[i]);136 memset(map,false,sizeof(map));137 while(m--){138 scanf("%d%d",&u,&v);139 map[u][v]=true;140 }141 Build();142 printf("%d\n",SAP(vs,vt));143 memset(mark,false,sizeof(mark));144 dfs(vs);145 cnt=0;146 for(int i=1;i<=2*n;i++){147 if(!mark[i]&&i<=n)cnt++;148 else if(mark[i]&&i>n)cnt++;149 }150 printf("%d\n",cnt);151 for(int i=1;i<=2*n;i++){152 if(!mark[i]&&i<=n)printf("%d -\n",i);153 else if(mark[i]&&i>n)printf("%d +\n",i-n);154 }155 }156 return 0;157 }
0 0
- poj 2125(最小割)
- poj 2125 【最小割】
- poj 2125(最小割)
- poj 2125 最小割 最大流
- POJ 2125 最小割最大流
- poj 3084(最小割。。。。。)
- poj 3469 最小割
- poj 2914 最小割
- poj 3308 最小割
- poj 3469 最小割
- POJ 3308 最小割
- POJ 3469 最小割
- POJ 3308 最小割
- poj 3084 最小割
- POJ 3469 最小割
- 最小割-poj-2914
- poj 3084(最小割)
- poj 3469 最小割
- 矩阵小结
- poj 3469(网络流模版)
- 无法启动调试 未安装silverlight developer 运行时 解决办法
- hdu 4705(树形DP)
- hdu 4704(费马小定理)
- poj 2125(最小割)
- poj 2135(最小费用最大流)
- poj 2391(二分+最大流)
- poj 2455(二分+最大流)
- 张小龙演讲精华:产品经理的方法论与价值观
- poj 2987(最大权闭合图+割边最少)
- poj 3164(最小树形图)
- poj 3204(最小割)
- poj 3275(传递闭包)