poj3436:http://poj.org/problem?id=3436
题意:有一些机器用来构成一个组装电脑的生产线,每台机器对输入机器的电脑有要求,符合要求的电脑被送入机器后会输出一台规定配件情况的电脑。而且分别告知每台机器在单位时间内处理电脑的台数。将这些机器连成一个生产线,使得单位时间内出产的完整的电脑数量最多,完整的电脑就是具有所有配件的电脑。输出单位时间内的最大出产台数。
题解:每个机器是一个点,把源与所有没有必须元件的点连接,所有完整元件的点与汇连接,若一台机器的输出能符合另一台机器的输入条件则连一条边。把每个机器拆点,其内部边流量为其生产速度。
1 #include<iostream> 2 #include<cstring> 3 #include<queue> 4 #include<cstdio> 5 #include<algorithm> 6 #define min(a,b)(a<b?a:b) 7 #define INF 1000000 8 using namespace std; 9 const int MAX=610; 10 const int N=610; 11 struct Node { 12 int c; 13 int f; 14 }; 15 int sx,ex,p;//sx和ex分别代表源点和汇点 16 int pre[MAX]; 17 Node map[MAX][MAX]; 18 int n,m; 19 bool BFS() { //BFS搜索层次网络 20 memset(pre,0,sizeof(pre)); 21 queue< int > Q; 22 Q.push(sx); 23 pre[sx]=1; 24 while(!Q.empty()) { 25 int d=Q.front(); 26 Q.pop(); 27 for(int i=0; i<=2*n+1; i++) { 28 if(!pre[i]&&map[d][i].c-map[d][i].f) { 29 pre[i]=pre[d]+1; 30 Q.push(i); 31 } 32 } 33 } 34 return pre[ex]!=0; 35 } 36 int dinic(int pos,int flow) { //pos是顶点号,flow是当前顶点所能得到的流量,一次dinic只能求出一次增加的流量, 37 int f=flow; 38 if(pos==ex) 39 return flow; 40 for(int i=0; i<=2*n+1; i++) { 41 if(map[pos][i].c-map[pos][i].f&&pre[pos]+1==pre[i]) { 42 int a=map[pos][i].c-map[pos][i].f; 43 int t=dinic(i,min(a,flow)); 44 map[pos][i].f+=t; 45 map[i][pos].f-=t; 46 flow-=t; 47 if(flow<=0)break; 48 //我最开始就是这里没弄明白,我不明白为什么要此顶点得到的流量减去改变量; 49 //答案就在下面的 return f-flow; 50 } 51 } 52 if(f-flow<=0)pre[pos]=-1; 53 return f-flow;//其实这里返回给他前一层的就是这个t;因为t在层函数里面都有,所以所过避免重复就写成这样; 54 } 55 int solve(){ 56 int sum=0; 57 while(BFS()) { 58 sum+=dinic(sx,INF); 59 //printf("dada\n"); 60 } 61 return sum; 62 } 63 bool check0(int a[]){ 64 for(int i=1;i<=p;i++){ 65 if(a[i]==1)return false; 66 } 67 return true; 68 } 69 bool checkt(int a[]){ 70 for(int i=1;i<=p;i++){ 71 if(a[i]==0)return false; 72 } 73 return true; 74 } 75 bool check1(int a[],int b[]){ 76 bool flag=true; 77 for(int k=1;k<=p;k++){ 78 if(a[k]==1 && b[k]==0) 79 flag=false; 80 if(a[k]==0 && b[k]==1) 81 flag=false; 82 if(!flag) break; 83 } 84 if(flag) 85 return true; 86 else return false; 87 } 88 struct Edge{ 89 int ss[200]; 90 }in[N],out[N]; 91 int val[N],ct; 92 int main(){ 93 while(~scanf("%d%d",&p,&n)){ 94 memset(val,0,sizeof(val)); 95 memset(in,0,sizeof(in)); 96 memset(out,0,sizeof(out)); 97 memset(map,0,sizeof(map)); 98 for(int i=1;i<=n;i++){ 99 scanf("%d",&val[i]); 100 for(int j=1;j<=p;j++) 101 scanf("%d",&in[i].ss[j]); 102 for(int j=1;j<=p;j++) 103 scanf("%d",&out[i].ss[j]); 104 } 105 for(int i=1;i<=n;i++){ 106 if(check0(in[i].ss)) 107 map[0][i].c=INF; 108 if(checkt(out[i].ss)) 109 map[i+n][2*n+1].c=INF; 110 } 111 for(int i=1;i<=n;i++) 112 for(int j=1;j<=n;j++) 113 if(check1(out[i].ss,in[j].ss)&&i!=j) 114 map[i+n][j].c=INF; 115 for(int i=1;i<=n;i++) 116 map[i][i+n].c=val[i]; 117 ex=2*n+1;sx=0;ct=0; 118 int result=solve(); 119 for(int i=1+n;i<=2*n;i++) 120 for(int j=1;j<=n;j++) 121 if(map[i][j].f>0) 122 ct++; 123 printf("%d %d\n",result,ct); 124 for(int i=1+n;i<=2*n;i++) 125 for(int j=1;j<=n;j++) 126 if(map[i][j].f>0){ 127 printf("%d %d %d\n",i-n,j,map[i][j].f); 128 } 129 130 } 131 return 0; 132 133 }
时间: 2024-11-06 11:17:50