poj3436网络流之最大流拆点
Posted walfy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj3436网络流之最大流拆点相关的知识,希望对你有一定的参考价值。
这题看了半天看不懂题意。。。还是看的网上题意写的
加一个源点一个汇点,把每个点拆成两个,这两个点的流量是v,其他联通的边都设为无穷大
输入没有1的点就与源点连接,输出只有1的点就与汇点连接
还有这个输出技巧,因为每条反向弧初始容量设置为0,因此完成增广之后,反向弧的容量即为路径。
#include<map> #include<set> #include<cmath> #include<queue> #include<stack> #include<vector> #include<cstdio> #include<cassert> #include<iomanip> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #define pi acos(-1) #define ll long long #define mod 10007 #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; const double g=10.0,eps=1e-9; const int N=200+5,maxn=200+5,inf=0x3fffff; int a[N][20]; int s,t,n,p,pre[N]; bool vis[N]; int c[N][N]; bool bfs() { memset(pre,0,sizeof pre); memset(vis,0,sizeof vis); vis[s]=1; queue<int>q; q.push(s); while(!q.empty()){ int x=q.front(); q.pop(); if(x==t)return 1; for(int i=0;i<=2*n+1;i++) { if(!vis[i]&&c[x][i]) { vis[i]=1; q.push(i); pre[i]=x; } } } return 0; } int max_flow() { int ans=0; while(1){ if(!bfs())break; int minn=inf; for(int i=t;i!=s;i=pre[i]) minn=min(minn,c[pre[i]][i]); for(int i=t;i!=s;i=pre[i]) { c[pre[i]][i]-=minn; c[i][pre[i]]+=minn; } ans+=minn; } cout<<ans<<" "; } int main() { ios::sync_with_stdio(false); cin.tie(0); // cout<<setiosflags(ios::fixed)<<setprecision(2); while(cin>>p>>n){ memset(c,0,sizeof(c)); for(int i=1;i<=n;i++) { cin>>c[i][i+n]; for(int j=1;j<=p;j++)cin>>a[i][j]; for(int j=1;j<=p;j++)cin>>a[i+n][j]; } for(int i=1;i<=n;i++) { bool flag=1; for(int j=1;j<=p;j++) if(a[i][j]==1) { flag=0; break; } if(flag)c[0][i]=inf; flag=1; for(int j=1;j<=p;j++) if(a[i+n][j]!=1) { flag=0; break; } if(flag)c[i+n][2*n+1]=inf; } for(int i=n+1;i<=2*n;i++)//前驱 { for(int j=1;j<=n;j++)//后继 { bool flag=1; for(int l=1;l<=p;l++) { if(a[j][l]+a[i][l]==1) { flag=0; break; } } if(flag)c[i][j]=inf; } } /* for(int i=0;i<=2*n+1;i++) { for(int j=0;j<=2*n+1;j++) cout<<c[i][j]<<" "; cout<<endl; }*/ s=0;t=2*n+1;//t是汇点 max_flow(); int cnt=0,a1[N],a2[N],a3[N]; for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { if(i!=j&&c[j][i+n]>0) { ++cnt; a1[cnt]=i; a2[cnt]=j; a3[cnt]=c[j][i+n]; } } } cout<<cnt<<endl; for(int i=1;i<=cnt;i++) cout<<a1[i]<<" "<<a2[i]<<" "<<a3[i]<<endl; } return 0; }
以上是关于poj3436网络流之最大流拆点的主要内容,如果未能解决你的问题,请参考以下文章