poj 3436 ACM Computer Factory
建图题。
题意:N台机器流水作业,每台机器的输入输出各有P个参数。其中0和1分别表示不存在、存在;2表示可有可无(可以是0,也可以是1)。2只会出现在输入参数中。
分析:题目间接建图,首先设立超级源s、超级汇t。s连所有输入参数为0的机器,所有输出参数为1的机器连t。然后每台机器的输出参数与其他机器的输入参数比较,符合要求就连边。建好图后套模板就好了。注意输出要求:把能得到最大流的增广路记录下来,打印出哪两台机器相连(流水作业,有先后顺序的),以及这条边上的流。
坑:1、由于是Special Judge,只需输出一组可行解,即使是Sample,输出也可以不一样。
2、拆点:以机器建点,把输入输出拆成两个点u、v,w就是机器的工作量。拆点之后点的数量和边的数量增加了。
3、可恶的“2”:与s连边的要求是参数全为0,由于输入参数中有“2”这个混子,所以即使输入参数全为2,也可以与超级源s连边。
4、数据有问题??反正我没发现。。。讨论区里说数据不足就用0代替。
View Code
1 #include<stdio.h> 2 #include<string.h> 3 #define MIN(a,b) a>b?b:a 4 #define NUM 110 5 #define INF 0x7ffffff 6 int map[NUM][15]; 7 typedef struct{ 8 int e,f,next; 9 }info; 10 info edge[NUM*NUM]; 11 int head[NUM]; 12 int Que[NUM*2]; 13 int level[NUM]; 14 int connect[1000][3]; 15 int N,P; 16 int st,ed; 17 int tol,tot; 18 int CHECK(int a,int b) 19 { 20 for(int i=1;i<=P;i++) 21 { 22 if(map[a][i]+map[b][i]==1)return 0; 23 } 24 return 1; 25 } 26 void Add(int s,int t,int c) 27 { 28 edge[tol].e=t; 29 edge[tol].f=c; 30 edge[tol].next=head[s]; 31 head[s]=tol++; 32 edge[tol].e=s; 33 edge[tol].f=0; 34 edge[tol].next=head[t]; 35 head[t]=tol++; 36 } 37 int BFS() 38 { 39 int fr,tp,next,cur_level,cur; 40 memset(level,-1,sizeof(level)); 41 Que[0]=st; 42 level[st]=0; 43 for(fr=0,tp=1;fr!=tp;fr=(fr+1)) 44 { 45 cur=Que[fr]; 46 cur_level=level[cur]; 47 for(next=head[cur];next!=-1;next=edge[next].next) 48 { 49 if(edge[next].f&&level[edge[next].e]==-1){ 50 Que[tp]=edge[next].e; 51 level[edge[next].e]=cur_level+1; 52 tp=(tp+1); 53 54 } 55 } 56 } 57 return level[ed]!=-1; 58 } 59 int DFS(int s,int min) 60 { 61 int r=0,next; 62 int t; 63 if(s==ed) 64 return min; 65 for(next=head[s];r<min&&next!=-1;next=edge[next].next) 66 { 67 if(edge[next].f&&level[s]+1==level[edge[next].e]){ 68 t=MIN(min-r,edge[next].f); 69 t=DFS(edge[next].e,t); 70 if(t&&edge[next].e!=s&&(edge[next].e-s!=N&&s-edge[next].e!=N)&&(s!=st&&edge[next].e!=ed)){ 71 connect[tot][0]=s; 72 connect[tot][1]=edge[next].e; 73 connect[tot++][2]=t; 74 } 75 r+=t; 76 edge[next].f-=t; 77 edge[next^1].f+=t; 78 } 79 } 80 if(!r)level[s]=-2; 81 return r; 82 } 83 int main() 84 { 85 int res,t,cnt=0; 86 int i,j,w; 87 char str[20]; 88 while(scanf("%d%d",&P,&N)!=EOF) 89 { 90 for(i=0;i<N;i++) 91 { 92 scanf("%d",&w); 93 94 map[i][0]=w; 95 for(j=1;j<=P;j++) 96 { 97 scanf("%d",&map[i][j]); 98 } 99 100 map[i+N][0]=w; 101 for(j=1;j<=P;j++) 102 { 103 scanf("%d",&map[i+N][j]); 104 } 105 } 106 st=2*N; 107 ed=st+1; 108 tol=0; 109 memset(head,-1,sizeof(head)); 110 for(i=0;i<N;i++) 111 { 112 for(j=1;j<=P&&map[i][j]!=1;j++){} 113 if(j>P)Add(st,i,map[i][0]); 114 } 115 for(i=N;i<2*N;i++) 116 { 117 for(j=1;j<=P&&map[i][j];j++){} 118 if(j>P)Add(i,ed,map[i][0]); 119 } 120 for(i=0;i<N;i++) 121 { 122 Add(i,i+N,INF); 123 } 124 for(i=0;i<N;i++) 125 { 126 for(j=N;j<2*N;j++) 127 { 128 if(CHECK(i,j)) 129 Add(j,i,MIN(map[i][0],map[j][0])); 130 } 131 } 132 res=0; 133 tot=0; 134 while(BFS()) 135 { 136 while(t=DFS(st,INF)) 137 { 138 res+=t; 139 } 140 } 141 printf("%d %d\n",res,tot); 142 for(i=0;i<tot;i++) 143 { 144 printf("%d %d %d\n",connect[i][0]-N+1,connect[i][1]+1,connect[i][2]); 145 } 146 } 147 return 0; 148 }