1 /* 2 题意:每一台computer都是有p部分组成,每一台机器都会对每台computer新加一些部分,删除一些部分,每一台机器每小时处理的computer的数量是固定的;给出的参数中,p个S表示对输入的p个部分的零件的要求:0表示必须没有,1表示必须有,2表示无所谓,p个D表示经过该机器后输出的p个部分零件的结果:0表示没有,1表示有;Q表示单位时间可处理的computer数量,最终求怎样安排这些机器的处理过程使得输出的效率最大; 3 4 题解:最大流 5 构图:将n台机器拆分成2*n个点,i->i+n表示当前机器i能处理的computer台数,然后将可以互相连接(即输入的p部分与输出的p部分需要相符合)的点连接,此处我用i+n连接j,表示机器i输出的computer可以由机器j处理,然后再加源点0,它的p部分的输出均为0,与1~n判断能否连接后再相连,权值为无限大,汇点的p部分输入均为1,n+1~2*n与汇点2*n+1判断后再相连,边权值为无限大;然后求源点到汇点的最大流即可。 6 */ 7 #include <cstdio> 8 #include <cstring> 9 10 #define MAXN 205 11 #define inf 1000000000 12 13 int max_flow(int n,int mat[][MAXN],int source,int sink,int flow[][MAXN]){ 14 int pre[MAXN],que[MAXN],d[MAXN],p,q,t,i,j; 15 if (source==sink) return inf; 16 for (i=0;i<n;i++) 17 for (j=0;j<n;flow[i][j++]=0); 18 for (;;){ 19 for (i=0;i<n;pre[i++]=0); 20 pre[t=source]=source+1,d[t]=inf; 21 for (p=q=0;p<=q&&!pre[sink];t=que[p++]) 22 for (i=0;i<n;i++) 23 if (!pre[i] && (j=mat[t][i]-flow[t][i])) 24 pre[que[q++]=i]=t+1,d[i]=d[t]<j?d[t]:j; 25 else if (!pre[i]&&(j=flow[i][t])) 26 pre[que[q++]=i]=-t-1,d[i]=d[t]<j?d[t]:j; 27 if (!pre[sink]) break; 28 for (i=sink;i!=source;) 29 if (pre[i]>0) 30 flow[pre[i]-1][i]+=d[sink],i=pre[i]-1; 31 else 32 flow[i][-pre[i]-1]-=d[sink],i=-pre[i]-1; 33 } 34 for (j=i=0;i<n; j+=flow[source][i++]); 35 return j; 36 } 37 38 struct node 39 { 40 int q; 41 int s[11],d[11]; 42 }nodes[55]; 43 44 int p; 45 46 bool match(node a, node b) 47 { 48 for(int i=0; i<p; i++) 49 if (a.d[i] != b.s[i] && b.s[i] != 2) 50 return false; 51 return true; 52 } 53 54 int main(void) 55 { 56 int n; 57 int mat[MAXN][MAXN]; 58 int flow[MAXN][MAXN]; 59 while (~scanf("%d%d",&p,&n)) 60 { 61 memset(mat,0,sizeof(mat)); 62 for(int i=1; i<=n; i++) 63 { 64 scanf("%d",&nodes[i].q); 65 mat[i][i+n] = nodes[i].q; // 拆点 66 for(int j=0; j<p; j++) 67 scanf("%d",&nodes[i].s[j]); 68 for(int j=0; j<p; j++) 69 scanf("%d",&nodes[i].d[j]); 70 } 71 72 for(int i=0; i<p; i++) 73 { 74 nodes[0].d[i] = 0; 75 nodes[n+1].s[i] = 1; 76 } 77 78 for(int i=1; i<=n; i++) 79 { 80 if (match(nodes[0],nodes[i])) 81 mat[0][i] = 10005; 82 if (match(nodes[i],nodes[n+1])) 83 mat[i+n][2*n+1] = 10005; 84 } 85 for(int i=1; i<=n; i++) 86 for(int j=1; j<=n; j++) 87 if (i != j && match(nodes[i],nodes[j])) 88 mat[i+n][j] = nodes[i].q; 89 90 printf("%d ",max_flow(2*n+2,mat,0,2*n+1,flow)); 91 92 int sum = 0; 93 for(int i=1; i<=n; i++) 94 for(int j=1; j<=n; j++) 95 if (flow[i+n][j]) 96 sum++; 97 printf("%d\n",sum); 98 for(int i=1; i<=n; i++) 99 for(int j=1; j<=n; j++) 100 if (flow[i+n][j] > 0) 101 printf("%d %d %d\n",i,j,flow[i+n][j]); 102 } 103 return 0; 104 }