標籤:style color strong io 資料 for ar 工作
POJ 3436 ACM Computer Factory
電腦公司生產電腦有N個機器,每個機器單位時間產量為Qi。
電腦由P個組件組成,每個機器工作時只能把有某些組件的半成品電腦(或什麼都沒有的空電腦)變成有另一些組件的半成品電腦或完整電腦(也可能移除某些組件)。求電腦公司的單位時間最大產量,以及哪些機器有協作關係,即一台機器把它的產品交給哪些機器加工。
Sample input
3 4
15 0 0 0 0 1 0
10 0 0 0 0 1 1
30 0 1 2 1 1 1
3 0 2 1 1 1 1
Sample output
25 2
1 3 15
2 3 10
輸入:電腦由3個組件組成,共有4台機器,1號機器產量15, 能給空電腦加上2號組件,2號 機器能給空電腦加上2號組件和3號組件, 3號機器能把有1個2號組件和3號組件有無均可的電腦變成成品(每種組件各有一個)
輸出:單位時間最大產量25,有兩台機器有協作關係,
1號機器單位時間內要將15個電腦給3號機器加工
2號機器單位時間內要將10個電腦給3號機器加工
資料規模很小,用EdmondsKarp就可以了。主要題目不僅要求最大流的值還要輸出有流流過的邊。
仔細想一想,這題不用拆點!
#include<cstdio>#include<cstring>#include<algorithm>#include<queue>#include<vector>using namespace std;typedef long long LL;const int maxn = 60;const int inf = 0x7fffffff;struct Edge { int from,to,cap,flow; Edge(int u,int v,int c,int f):from(u),to(v),cap(c),flow(f) {}};struct EdmondsKarp { int n,m; vector<Edge> edges; vector<int> G[maxn]; int p[maxn]; int a[maxn]; void init(int n) { this->n=n; for(int i=0; i<n; i++) G[i].clear(); edges.clear(); } void AddEdge(int from,int to,int cap) { edges.push_back(Edge(from,to,cap,0)); edges.push_back(Edge(to,from,0,0)); m=edges.size(); G[from].push_back(m-2); G[to].push_back(m-1); } int Maxflow(int s,int t) { int flow=0; while(true) { memset(a,0,sizeof(a)); queue<int> Q; Q.push(s); a[s]=inf; while(!Q.empty()) { int x=Q.front(); Q.pop(); for(int i=0; i<G[x].size(); i++) { Edge &e=edges[G[x][i]]; if(!a[e.to]&&e.cap>e.flow) { a[e.to]=min(a[x],e.cap-e.flow); p[e.to]=G[x][i]; Q.push(e.to); if(e.to==t) break; } } if(a[t])break; } if(!a[t])break; for(int u=t; u!=s; u=edges[p[u]].from) { edges[p[u]].flow+=a[t]; edges[p[u]^1].flow-=a[t]; } flow+=a[t]; } return flow; }};EdmondsKarp solver;int P, N;int w[maxn], in[maxn][12], out[maxn][12];int print[maxn][5], cnt;int main(){ int i, j; bool flag; while(~scanf("%d%d", &P, &N)) { int s = 0, t = N+1; solver.init(N+2); for(int i=1; i<=N; ++i) { scanf("%d", &w[i]); flag = true; for(j=0; j<P; ++j) { scanf("%d", &in[i][j]); if(in[i][j]==1) flag = false; } if(flag) solver.AddEdge(s, i, w[i]); flag = true; for(j=0; j<P; ++j) { scanf("%d", &out[i][j]); if(out[i][j]!=1) flag = false; } if(flag) solver.AddEdge(i, t, w[i]); } for(i=1; i<=N; ++i) { for(j=1; j<=N; ++j) { if(i==j) continue; flag = true; for(int k=0; k<P; ++k) if(out[i][k] + in[j][k] == 1) { flag = false; break; } if(flag) solver.AddEdge(i, j, min(w[i], w[j])); } } printf("%d ", solver.Maxflow(s, t)); cnt = 0; for(i=1; i<=N; ++i) for(j=0; j<solver.G[i].size(); ++j) { Edge &e = solver.edges[solver.G[i][j]]; if(e.flow>0 && e.to != t && e.from != s) { print[cnt][0] = e.from; print[cnt][1] = e.to; print[cnt++][2] = e.flow; } } printf("%d\n", cnt); for(i=0; i<cnt; ++i) printf("%d %d %d\n", print[i][0],print[i][1],print[i][2]); } return 0;}