標籤:
解題報告 之 POJ3463 ACM Computer Factory
Description
As you know, all the computers used for ACM contests must be identical, so the participants compete on equal terms. That is why all these computers are historically produced at the same factory.
Every ACM computer consists of P parts. When all these parts are present, the computer is ready and can be shipped to one of the numerous ACM contests.
Computer manufacturing is fully automated by using N various machines. Each machine removes some parts from a half-finished computer and adds some new parts (removing of parts is sometimes necessary as the parts cannot be added to a computer in arbitrary order). Each machine is described by its performance (measured in computers per hour), input and output specification.
Input specification describes which parts must be present in a half-finished computer for the machine to be able to operate on it. The specification is a set of P numbers 0, 1 or 2 (one number for each part), where 0 means that corresponding part must not be present, 1 — the part is required, 2 — presence of the part doesn‘t matter.
Output specification describes the result of the operation, and is a set of P numbers 0 or 1, where 0 means that the part is absent, 1 — the part is present.
The machines are connected by very fast production lines so that delivery time is negligibly small compared to production time.
After many years of operation the overall performance of the ACM Computer Factory became insufficient for satisfying the growing contest needs. That is why ACM directorate decided to upgrade the factory.
As different machines were installed in different time periods, they were often not optimally connected to the existing factory machines. It was noted that the easiest way to upgrade the factory is to rearrange production lines. ACM directorate decided to entrust you with solving this problem.
Input
Input file contains integers PN, then N descriptions of the machines. The description of ith machine is represented as by 2 P + 1 integers QiSi,1Si,2...Si,PDi,1Di,2...Di,P, where Qi specifies performance, Si,j — input specification for part j, Di,k — output specification for part k.
Constraints
1 ≤ P ≤ 10, 1 ≤ N ≤ 50, 1 ≤ Qi ≤ 10000
Output
Output the maximum possible overall performance, then M — number of connections that must be made, then M descriptions of the connections. Each connection between machines A and B must be described by three positive numbers ABW, where W is the number of computers delivered from A to B per hour.
If several solutions exist, output any of them.
Sample Input
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 1
3 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 1
2 2100 0 0 1 0200 0 1 1 1
Sample Output
25 21 3 15
2 3 104 51 3 33 5 31 2 12 4 14 5 1
0 0
題目大意:現在你要組裝電腦,一台電腦由p個組件構成,現在有n台組裝機。每一台組裝機接收一定格式的半成品(輸入中會給出組裝機i的輸入需要滿足的格式,對於組件j,1表示該組件要有,0表示該組件必須沒有,2表示該組件可有可無),輸出組裝後另一種格式的半成品(或成品,即全部為1)。每台組裝機有一個組裝能力cap。問你最多能組裝多少台電腦?並且每台組裝機相互之間是傳遞了多少半成品。
分析:憑藉著我高超的閱讀理解能力以及強大的網路流功底(怎麼我自己都不相信?!)。一看就明顯是最大流,而且思路都很清晰啊,拆點,超級源點匯點,以及殘餘網路流量判定。居然在一個細節被坑了三個小時。。
好吧說正題:怎麼構造最大流呢?首先所有組裝機拆點,負載為組裝機的cap,以此限制流量。然後如果該組裝機要求的輸入格式為全0(即接受還未開始組裝的電腦),那麼超級源點與該組裝機相連,負載為INF;如果組裝機輸出格式為全1,則該組裝機與超級匯點相連,負載為INF。然後遍曆任意兩台組裝機i、j,如果out[i]滿足in[j] ---> 即第i台組裝機的輸出格式滿足第j台組裝機的輸入格式,那麼就連一條邊,負載為INF。至此跑最大流看看是多少即可。對於殘餘網路,你去掃描所有從組裝機入點(拆點後的入點)所串連的所有邊,篩選出既不是串連des,也不是串連拆點的出點的那些邊,輸出即可。
如果看到這裡你都覺得沒問題的話:那麼你就跟我犯了一樣的錯誤。那麼錯誤在哪呢? 源點與組裝機串連的條件並不要求組裝機輸入格式為全0,還可以有2!(仔細想想)。所以判斷的時候應該統一用match函數(見代碼)而非使用in[i]==string(p,‘0‘)這種炫技作死的手法(p表示零件數)。 BTW,似乎也有不拆點的方法,但是資料量很小所以拆不拆其實差不多。
上代碼:
#include<iostream>#include<cstdio>#include<algorithm>#include<queue>#include<cstring>#include<string>using namespace std;const int MAXM = 251000;const int MAXN = 510;const int INF = 0x3f3f3f3f;struct Edge{int from, to, cap, next, oricap;};Edge edge[MAXM];int output[MAXM];int level[MAXN];int head[MAXN];int cap[MAXN];string in[MAXN];string out[MAXN];int src, des, cnt;bool match( string out, string in, int p ){for (int i = 0; i < p; i++)if (out[i] + in[i] == '0' + '1')return false;return true;}void addedge( int from, int to, int cap ){edge[cnt].from = from;edge[cnt].to = to;edge[cnt].cap = edge[cnt].oricap = cap;edge[cnt].next = head[from];head[from] = cnt++;swap( from, to );edge[cnt].from = from;edge[cnt].to = to;edge[cnt].cap = edge[cnt].oricap = 0;edge[cnt].next = head[from];head[from] = cnt++;}int bfs( ){memset( level, -1, sizeof level );queue<int>q;while (!q.empty( ))q.pop( );level[src] = 0;q.push( src );while (!q.empty( )){int u = q.front( );q.pop( );for (int i = head[u]; i != -1; i = edge[i].next){int v = edge[i].to;if (edge[i].cap > 0 && level[v] == -1){level[v] = level[u] + 1;q.push( v );}}}return level[des] != -1;}int dfs( int u, int f ){if (u == des) return f;int tem;for (int i = head[u]; i != -1; i = edge[i].next){int v = edge[i].to;if (edge[i].cap>0 && level[v] == level[u] + 1){tem = dfs( v, min( f, edge[i].cap ) );if (tem > 0){edge[i].cap -= tem;edge[i ^ 1].cap += tem;return tem;}}}level[u] = -1;return 0;}int Dinic( ){int ans = 0, tem;while (bfs( )){while ((tem = dfs( src, INF )) > 0){ans += tem;}}return ans;}int main( ){int p, n;src = 0;des = 505;while (cin >> p >> n){memset( head, -1, sizeof head );cnt = 0;for (int i = 1; i <= n; i++){cin >> cap[i];in[i] = out[i] = "";char ch;for (int j = 1; j <= p; j++){cin >> ch;in[i] += ch;}for (int j = 1; j <= p; j++){cin >> ch;out[i] += ch;}}for (int i = 1; i <= n; i++){addedge( i, i + 50, cap[i] );if (match(in[i],string(p,'0'),p))addedge( src, i, INF );if (match(out[i],string(p,'1'),p))addedge( i + 50, des, INF );for (int j = 1; j <= n; j++)if (match( out[i], in[j], p ))addedge( i + 50, j, INF );}int ans = Dinic( );int num = 0;for (int i = 1 + 50; i <= n + 50; i++){for (int j = head[i]; j != -1; j = edge[j].next){if (edge[j].from == edge[j].to + 50 || edge[j].to == des) continue;if (edge[j].oricap > edge[j].cap) output[num++] = j;}}printf( "%d %d\n", ans, num );for (int i = 0; i < num; i++){printf( "%d %d %d\n", edge[output[i]].from - 50, edge[output[i]].to, edge[output[i]].oricap - edge[output[i]].cap );}}return 0;}
好了我要去趕MATLAB的作業了。。尼瑪這個細節我終身難忘。再次證明了構圖是最大流最難的部分!!
解題報告 之 POJ3463 ACM Computer Factory