標籤:
題 意:有一個ACM工廠會生產一些電腦,在這個工廠裡面有一些生產線,分別生產不同的零件,不過他們生產的電腦可能是一體機,所以只能一些零件加工後別的生 產線才可以繼續加工,比如產品A在生產線1號加工後繼續前往生產線2號繼續加工,直到成為完全產品。輸入 P 意思是這個電腦需要P個零件,N表示有N個生產線,每個生產線都有最大加工量,並且需要什麼零件和輸出的是什麼零件,0表示沒有這個零件,1表示有這個零 件,2表示有沒有都可以。
範例說明:
3 4
1號: 15 0 0 0 --> 0 1 0
2號: 10 0 0 0--> 0 1 1
3號: 30 0 1 2 --> 1 1 1
4號: 3 0 2 1 --> 1 1 1
1號生產線需要0 0 0這樣的零件(這樣的零件也就是無限制零件,源點),它可以把零件加工成 0 1 0 這個樣子,然後 3 號生產線可以接受這種零件,並且加工成 1 1 1 也就是成品,到這樣也就加工成功了,因為1號生產線每次可以加工 15 個零件,所以1->3的加工量就是 15,同理 2->3的加工量是 10,所以結果是 25。
分析:很明顯的網路流題目,感覺痛點應該在題目閱讀和建圖上.....可以用0當做源點 N+1當做匯點,然後每兩點都進行匹配一些,看看是否可以串連,路徑的權值為出點的生產能力。
注意:因為每個生產線的生產能力有限,所以需要拆點,防止超出他的生產能力,比如如果不拆點結果就會使20,實際上是10
#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <queue>using namespace std;const int oo=0x3f3f3f3f;struct node{ int flow; int in[55]; int out[55];}a[20];int maps[111][111];int x[10005];int y[10005],z[10005];int oldmaps[111][111];int layer[111];int p,n;void init(){ memset(maps,0,sizeof(maps)); memset(oldmaps,0,sizeof(oldmaps)); for(int i=1;i<=p;i++) { a[1].in[i]=0; a[1].out[i]=0; a[n+2].in[i]=1; a[n+2].out[i]=1; } a[1].flow=oo; a[n+2].flow=oo;}int can(int x,int y){ for(int i=1;i<=p;i++) { if(a[x].out[i]!=a[y].in[i]&&a[y].in[i]!=2) return 0; } return 1;}int bfs(int s,int End){ memset(layer,0,sizeof(layer)); queue<int>q; q.push(s); layer[s]=1; while(q.size()) { s=q.front(); q.pop(); if(s==End) { return 1; } for(int i=1;i<=End;i++) { if(maps[s][i]&&layer[i]==0) { layer[i]=layer[s]+1; q.push(i); } } } return 0;}int dfs(int s,int End,int maxflow){ if(s==End) return maxflow; int iflow=0; for(int i=1;i<=End;i++) { if(maps[s][i]>0&&layer[s]==layer[i]-1) { int flow=min(maxflow-iflow,maps[s][i]); flow=dfs(i,End,flow); maps[s][i]-=flow; maps[i][s]+=flow; iflow+=flow; if(maxflow==iflow) break; } } return iflow;}int Dinic(){ int max_flow=0; while(bfs(1,n*2)) { max_flow+=dfs(1,n*2,oo); } return max_flow;}int main(){ while(~scanf("%d%d",&p,&n)) { init(); for(int i=2; i<=n+1; i++) { scanf("%d",&a[i].flow); for(int j=1; j<=p; j++) { scanf("%d",&a[i].in[j]); } for(int j=1;j<=p;j++) { scanf("%d",&a[i].out[j]); } } n+=2; for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { if(i==j) { oldmaps[i][j+n]=maps[i][j+n]=a[i].flow; } else { if(can(i,j)) oldmaps[i+n][j]=maps[i+n][j]=min(a[i].flow,a[j].flow); else oldmaps[i+n][j]=maps[i+n][j]=0; } } } int sum=Dinic(); int k=0; for(int i=2;i<n;i++) { for(int j=2;j<n;j++) { if(maps[i+n][j]<oldmaps[i+n][j]) { x[k]=i;y[k]=j; z[k]=oldmaps[i+n][j]-maps[i+n][j]; k++; } } } printf("%d %d\n",sum,k); for(int i=0;i<k;i++) printf("%d %d %d\n",x[i]-1,y[i]-1,z[i]); } return 0;}/*3 415 0 0 0 0 1 010 0 0 0 0 1 130 0 1 2 1 1 13 0 2 1 1 1 13 55 0 0 0 0 1 0100 0 1 0 1 0 13 0 1 0 1 1 01 1 0 1 1 1 0300 1 1 2 1 1 12 2100 0 0 1 0200 0 1 1 1*/
A - ACM Computer Factory - poj 3436(最大流)