题目连接:http://poj.org/problem?id=3436
英语不好,直接在网上搜的题意、、、很详细
题意:电脑工厂有N台机器,每台机器对半成品电脑进行加工。每个电脑由P个部件组成,用0和1表示某部件是否已存在
(1表示存在了)。
每台机器对加工的电脑都是有要求的,只有满足要求,才能进入机器进行加工。
机器对电脑部件的要求用0,1,2表示,输入的P个数中,第i个数为ai,ai=0表示该半成品电脑不能有部件i,ai=1表示
该半成品必须已有部件i(即1),ai=2表示有没有此部件都无关系。
进入机器加工后的电脑出来后所含部件情况用P个数字(0或1)表示。
输入:P和N,接下来N行介绍N个机器,第一个数Q,表示单位时间此机器能加工的电脑数(我是这么理解的),接下来两
个数串,第一个P个数(0,1,2序列)表示该机器的对电脑所含部件的要求,第二个P个数(0,1序列)表示经该机器加工
后,输出的电脑所含部件的情况。
输出:单位时间能生产最多的电脑数,然后输出必须给N台机器间连接的生产线数。每行输出生产线的情况。起点U、终
点V,以及它们的权值W。
坑爹的一点是如果大家要用EK去做的话要用stack来进行搜索不能用queue。我也不知道为神马,discuss里面有。
一开始WA n遍,后来看了一组测试样例过了。注意与源点连接的条件。当然这题需要虚拟源点跟汇点。
代码:
View Code
#include <stdio.h> #include <string.h> #include <iostream> #include <stack> #include <algorithm> #define maxn 10050 using namespace std; struct machine { int pre[15],beh[15],out; }node[210]; int cap[210][210],pre[210]; int ans[210][210] = {0}; int pipei(int i,int j,int m) { int ii; for(ii = 1;ii <= m;ii++) { if(node[i].pre[ii] != 2) { if(node[i].pre[ii] == node[j].beh[ii]) continue; else return 0; } } return 1; } int is_yuan(int i,int n) { int j; for(j = 1;j <= n;j++) if(node[i].pre[j] == 1) return 0; return 1; } int flow[150][150],temp[150]; int ek(int n) { int i,j; stack<int>q; int u,v,nu,nv; nu = nv = 0; memset(flow,0,sizeof(flow)); int f = 0; for(;;) { memset(temp,0,sizeof(temp)); q.push(0); temp[0] = maxn; while(!q.empty()) { u = q.top(); q.pop(); for(v = 1;v <= n;v++) if(!temp[v] &&cap[u][v] > flow[u][v]) { pre[v] = u; q.push(v); if(cap[u][v]-flow[u][v] < temp[u]) temp[v] = cap[u][v]-flow[u][v],nu = u,nv = v; else temp[v] = temp[u]; } } if(temp[n] == 0) break; ans[nu][nv] += temp[n]; for(v = n;v != 0 ;v = pre[v]) { flow[pre[v]][v] += temp[n]; flow[v][pre[v]] -= temp[n]; } f += temp[n]; } return f; } int is_hui(int i,int n) { int j; for(j = 1;j <= n;j++) if(node[i].beh[j] != 1) return 0; return 1; } int main() { int i,j,n,p,count = 0; scanf("%d %d",&p,&n); memset(cap,0,sizeof(cap)); for(i = 1;i <= n;i++) { scanf("%d",&node[i].out); for(j = 1;j <= p;j++) scanf("%d",&node[i].pre[j]); for(j = 1;j <= p;j++) scanf("%d",&node[i].beh[j]); } for(i =1;i <= n;i++) if(is_yuan(i,p)) cap[0][i] = node[i].out; for(i =1;i <= n;i++) if(is_hui(i,p)) cap[i][n+1] = node[i].out; for(i =1;i <= n;i++) { for(j = 1;j <= n;j++) { if(i != j &&pipei(i,j,p)) cap[j][i] = node[j].out; } } int res; res = ek(n+1); printf("%d",res); int u; for(i = 1;i <= n;i++) { for(j = 1;j <= n;j++) if(flow[i][j] > 0) count++; } if(res) { cout<<" "<<count<<endl; for(i = 1;i <= n;i++) { for(j = 1;j <= n;j++) if(flow[i][j] > 0) cout<<i<<" "<<j<<" "<<flow[i][j]<<endl; } } else printf(" %d\n",count); return 0; }