1. 程式人生 > >poj3436網絡流之最大流拆點

poj3436網絡流之最大流拆點

hide ring 拆點 前驅 clas view int for fff

這題看了半天看不懂題意。。。還是看的網上題意寫的

加一個源點一個匯點,把每個點拆成兩個,這兩個點的流量是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; }
View Code

poj3436網絡流之最大流拆點