poj 3436(网络流)
这题也算是一个简单的网络流吧, 但是题目的意思看了好久才看懂, 然后一开始我还想错了, 一拿到题目我就往二进制转换上想了,所以想了很久都没有想出来,关键是最后哪一步要求出每次转移的机器, 如果用一种状态用一个数表示的话就很难求,。
后面看了下别人的才恍然大悟, 直接以每台机器作为点,然后拆点,连边就行了, 一般的网络流的做法。
还有一个就是怎么求出从那台机器转移到那台机器, 可以在用网络流记录有流流过的边。 然后再选出一些符合要求的就行了.
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 P N, then N descriptions of the machines. The description of ith machine is represented as by 2 P + 1 integers Qi Si,1 Si,2...Si,P Di,1 Di,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 A B W, where W is the number of computers delivered from A to B per hour. If several solutions exist, output any of them. Sample Input Sample input 1 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 input 2 3 5 5 0 0 0 0 1 0 100 0 1 0 1 0 1 3 0 1 0 1 1 0 1 1 0 1 1 1 0 300 1 1 2 1 1 1 Sample input 3 2 2 100 0 0 1 0 200 0 1 1 1 Sample Output Sample output 1 25 2 1 3 15 2 3 10 Sample output 2 4 5 1 3 3 3 5 3 1 2 1 2 4 1 4 5 1 Sample output 3 0 0 Hint Bold texts appearing in the sample sections are informative and do not form part of the actual data.
Source Northeastern Europe 2005, Far-Eastern Subregion
|
1 #include <stdio.h> 2 #include <string.h> 3 #include <string> 4 #include <iostream> 5 using namespace std; 6 #define INF 0x3ffffff 7 #define N 55 8 struct node 9 { 10 int to,next,w,from; 11 int sign; 12 }edge[10*N*N]; 13 // 你个2货,完写错了 14 15 struct node1 16 { 17 int u,v,w; 18 }save[N*N]; 19 20 int p,n; 21 int nn; 22 int s,t; 23 int cnt,pre[N]; 24 int saves[N][11],savet[N][11],savew[N]; 25 int lv[N],gap[N]; 26 27 void add_edge(int u,int v,int w) 28 { 29 edge[cnt].from=u; 30 edge[cnt].sign=0; 31 edge[cnt].to=v; 32 edge[cnt].w=w; 33 edge[cnt].next=pre[u]; 34 pre[u]=cnt++; 35 } 36 37 int sdfs(int k,int w) 38 { 39 if(k==t) return w; 40 int f=0; 41 int mi=nn-1; 42 for(int p=pre[k];p!=-1;p=edge[p].next) 43 { 44 int v=edge[p].to; 45 if(edge[p].w!=0) 46 { 47 if(lv[k]==lv[v]+1) 48 { 49 int tmp=sdfs(v,min(w-f,edge[p].w)); 50 if(tmp!=0) 51 edge[p].sign=1; 52 f+=tmp; 53 edge[p].w-=tmp; 54 edge[p^1].w+=tmp; 55 if(f==w||lv[s]==nn) return f; 56 } 57 if(lv[v]<mi) mi=lv[v]; 58 } 59 } 60 if(f==0) 61 { 62 gap[lv[k]]--; 63 if(gap[lv[k]]==0) 64 { 65 lv[s]=nn; 66 return f; 67 } 68 lv[k]=mi+1; 69 gap[lv[k]]++; 70 } 71 return f; 72 } 73 74 int sap() 75 { 76 nn=t+1; 77 int sum=0; 78 memset(lv,0,sizeof(lv)); 79 memset(gap,0,sizeof(gap)); 80 gap[0]=nn; 81 while( lv[s]<nn ) 82 { 83 sum += sdfs(s,INF); 84 } 85 return sum; 86 } 87 88 /*void dfs(int k,int sum,int w) 89 { 90 if(k==p) 91 { 92 sum++; 93 if(sum==1) 94 { 95 add_edge(s,sum,w); 96 add_edge(sum,s,0); 97 } 98 add_edge(sum,nn,w); 99 add_edge(nn,sum,0); 100 return ; 101 } 102 if(saves[k]==2) 103 { 104 dfs(k+1,sum*2+0,w); 105 dfs(k+1,sum*2+1,w); 106 } 107 else 108 { 109 dfs(k+1,sum*2+saves[k],w); 110 } 111 }*/ 112 113 int main() 114 { 115 memset(pre,-1,sizeof(pre)); 116 cnt=0; 117 scanf("%d%d",&p,&n); 118 s=0; 119 t=2*n+1; 120 for(int i=1;i<=n;i++) 121 { 122 scanf("%d",&savew[i]); 123 for(int j=0;j<p;j++) 124 scanf("%d",&saves[i][j]); 125 for(int j=0;j<p;j++) 126 scanf("%d",&savet[i][j]); 127 } 128 for(int i=1;i<=n;i++) // 构图, 以后还是用n个一次的构图方法吧 129 { 130 add_edge(i,n+i,savew[i]); 131 add_edge(n+i,i,0); 132 int flag=0; 133 for(int j=0;j<p;j++) 134 { 135 if(saves[i][j]==2) continue; 136 if(saves[i][j]!=0) 137 { 138 flag=1; break; 139 } 140 } 141 if(flag==0) 142 { 143 add_edge(s,i,INF); 144 add_edge(i,s,0); 145 } 146 flag=0; 147 for(int j=0;j<p;j++) 148 { 149 if(savet[i][j]!=1) 150 { 151 flag=1; 152 break; 153 } 154 } 155 if( flag==0 ) 156 { 157 add_edge(n+i,t,INF); 158 add_edge(t,n+i,0); 159 } 160 /////////////////////////////// 161 for(int j=1;j<=n;j++) 162 { 163 if(i==j) continue; 164 flag=0; 165 for(int k=0;k<p;k++) 166 { 167 if( saves[j][k]== 2) continue; 168 if(saves[j][k]!=savet[i][k]) 169 { 170 flag=1; 171 break; 172 } 173 } 174 if(flag==0) 175 { 176 add_edge(n+i,j,INF); 177 add_edge(j,n+i,0); 178 } 179 } 180 } 181 printf("%d ",sap()); 182 int tcnt=0; 183 for(int i=0;i<cnt;i+=2) 184 { 185 if( edge[i].sign == 1 ) 186 { 187 int x,y; 188 x=edge[i].from; 189 y=edge[i].to; 190 if(y==t||x==0) continue; 191 if(x>n) x-=n; 192 if(y>n) y-=n; 193 if(x==y) continue; 194 save[tcnt].u=x; 195 save[tcnt].v=y; 196 save[tcnt].w=edge[i^1].w; 197 tcnt++; 198 } 199 } 200 printf("%d\n",tcnt); 201 for(int i=0;i<tcnt;i++) 202 { 203 printf("%d %d %d\n",save[i].u,save[i].v,save[i].w); 204 } 205 return 0; 206 }