POJ 3436 ACM Computer Factory(拆点+前向星dinic)||(拆点+邻接矩阵dinic)||(不拆点+dinic))
来源:互联网 发布:领航者软件lhzsoft 编辑:程序博客网 时间:2024/04/28 22:15
题目大意:就是第一行两个数p,n分别代表电脑零件的个数,和有多少机器。接下来的n行每行2*p+1个数,第一个数为机器工作的效率,其余代表机器加工前和后电脑的变化,求机器一起工作的最大效率,并输出路径。
思路:由于源点的流入和普通链接点的流入,可能会大于当前点的容量,因此拆点.那么,怎么再判断有多少个机器用到了呢,这就要原来机器的工作效率,和剩余网络,如果原来的工作效率大于剩余网络那么一定该机器被用到了既有流。(注意建图时后来加源和汇,且机器和机器相连的时候应该注意到分开,因此就要相应的加上m值,但是应该加到i,j谁的值上,答案是i上因为如果加到j上相应的遍历的时候要减去m(Q[j].to-m)因为有逆向建图,所以在以a为下一个链接点时可能出现负值在vv[][]数组中 。)
法一:前向星
#include<iostream>#include<cstdio>#include<cstring>#include<map>#include<queue>#include<algorithm>#define MAX 1000#define inf 0x3f3f3f3fusing namespace std;struct node{ int w,in[52],out[52];}q[100];struct no{ int to,w,next;}Q[100000];int s,e,cnt,l[51100],qu[50000],head[50000];int vv[1100][1100];void bu(int a,int b,int c){ Q[cnt].to=b; Q[cnt].w=c; Q[cnt].next=head[a]; head[a]=cnt++; Q[cnt].to=a; Q[cnt].w=0; Q[cnt].next=head[b]; head[b]=cnt++;}int bfs(){ memset(l,-1,sizeof(l)); l[s]=0; queue<int>qu; while(!qu.empty()) qu.pop(); qu.push(s); while(!qu.empty()){ int v=qu.front(); qu.pop(); for(int i=head[v];~i;i=Q[i].next){ if( l[Q[i].to ]==-1&&Q[i].w>0 ){ l[Q[i].to ]=l[v]+1; qu.push(Q[i].to); } } } return l[e]!=-1;}int dfs(int x,int f){ if(x==e||!f) return f; int tmp=0,a; for(int i=head[x];~i;i=Q[i].next){ if(l[x]+1==l[Q[i].to ]&&Q[i].w>0 ){ a=dfs(Q[i].to,min(Q[i].w,f-tmp)); if(a>0){ Q[i].w-=a; Q[i^1].w+=a; tmp+=a; if(tmp==inf)break; } } } if(!tmp) l[x]=-1; return tmp;}int main(){ int n,m,j,i,k; while(~scanf("%d%d",&n,&m)){ cnt=0; memset(vv,0,sizeof(vv)); memset(head,-1,sizeof(head)); s=0,e=2*m+1; for(i=1;i<=m;i++){ int bj=false; scanf("%d",&q[i].w); bu(i,i+m,q[i].w);///***一般源和汇都是后来的时候才链接 for(j=0;j<n;j++){ scanf("%d",&q[i].in[j]); if(q[i].in[j]==1){ bj=true; } } if(!bj) bu(0,i,q[i].w); bj=false; for(j=0;j<n;j++){ scanf("%d",&q[i].out[j]); if(q[i].out[j]!=1){ bj=true; } } if(!bj) bu(i+m,2*m+1,q[i].w); } for(i=1;i<=m;i++){ for(j=1;j<=m;j++){ if(i==j)continue; bool vis=false; for(k=0;k<n;k++){ if( (q[i].out[k]!=q[j].in[k])&&q[j].in[k]!=2){ vis=true;break; } } if(!vis){ bu( i+m,j,q[i].w);///**** vv[m+i][j]=1; } } } int ans=0; while(bfs()){ ans+=dfs(s,inf); } int sum=0; for(i=1;i<=m;i++){///********* for(j=head[i+m];j!=-1;j=Q[j].next){ if( vv[i+m][Q[j].to ]&&Q[j].w<q[i].w ){ sum++; } } } printf("%d %d\n",ans,sum); for(i=1;i<=m;i++){ for(j=head[i+m];~j;j=Q[j].next){ if(vv[i+m][Q[j].to]&&Q[j].w<q[i].w){ printf("%d %d %d\n",i,Q[j].to,q[i].w-Q[j].w); } } } }}
法二:邻接矩阵+拆点dinic
#include<iostream>#include<cstdio>#include<cstring>#include<map>#include<queue>#include<algorithm>#define MAX 1000#define inf 0x3f3f3f3fusing namespace std;struct node{ int w,in[52],out[52];}q[100];int Map[1100][1100],s,e,l[1100];int flow[1100][1100];int bfs(){ memset(l,-1,sizeof(l)); l[s]=0; queue<int>Q; while(!Q.empty()) Q.pop(); Q.push(s); while(!Q.empty()){ int v=Q.front(); Q.pop(); for(int i=0;i<=e;i++){ if(Map[v][i]&&l[i]==-1){ l[i]=l[v]+1; Q.push(i); } } } return l[e]!=-1;}int dfs(int x,int f){ if(x==e||!f){ return f; } int tmp=0,a; for(int i=0;i<=e;i++){ if(l[i]==l[x]+1&&Map[x][i]){ a=dfs(i,min(Map[x][i],f-tmp)); if(a>0){ Map[x][i]-=a; Map[i][x]+=a; flow[x][i]+=a; flow[i][x]-=a; tmp+=a; if(tmp==f)break; } } } if(!tmp)l[x]=-1; return tmp;}int main(){ int n,m,i,j,k; while(~scanf("%d%d",&n,&m)){ memset(flow,0,sizeof(flow)); s=0,e=2*m+1; memset(Map,0,sizeof(Map)); for(i=1;i<=m;i++){ scanf("%d",&q[i].w); for(j=0;j<n;j++){ scanf("%d",&q[i].in[j]); } for(j=0;j<n;j++){ scanf("%d",&q[i].out[j]); } } bool bj; for(i=1;i<=m;i++){ for(j=1;j<=m;j++){ if(i!=j){ bj=false; for(k=0;k<n;k++){ if( (q[i].out[k]!=q[j].in[k])&&q[j].in[k]!=2){ bj=true;break; } } if(!bj){ Map[i+m][j]=q[i].w;///** } } } } for(i=1;i<=m;i++){ Map[i][i+m]=q[i].w; bj=false; for(j=0;j<n;j++){ if(q[i].in[j]==1){ bj=true;break; } } if(!bj){ Map[0][i]=q[i].w; } bj=false; for(j=0;j<n;j++){ if(q[i].out[j]!=1){ bj=true;break; } } if(!bj) Map[i+m][2*m+1]=q[i].w; } int ans=0; while(bfs()){ ans+=dfs(0,inf); } printf("%d ",ans); int sum=0; for(i=1;i<=e;i++){ for(j=1;j<=i;j++){ if(flow[i][j]>0) sum++; } } printf("%d\n",sum); for(i=1;i<=e;i++){ for(j=1;j<=i;j++){ if(flow[i][j]>0) printf("%d %d %d\n",i-m,j,flow[i][j]); } } } return 0;}法三:邻接矩阵不拆点(可能题目水了,不拆点也可以过,直接将上边代码的源点汇点和相邻的中间点去掉相应的m即可。)
1 0
- POJ 3436 ACM Computer Factory(拆点+前向星dinic)||(拆点+邻接矩阵dinic)||(不拆点+dinic))
- 【POJ 3436 ACM Computer Factory】网络流 & 拆点 & Dinic
- poj_3436 ACM Computer Factory(Dinic + 拆点)
- poj 3436 ACM Computer Factory(最大流Dinic拆点)
- POJ 3436 ACM Computer Factory(Dinic)
- poj3436--ACM Computer Factory(最大流,拆点dinic)
- POJ - 3436 ACM Computer Factory (ISAP EK Dinic)
- poj 3281(dinic+拆点)
- Poj 3436 ACM Computer Factory【最大流Dinic+建图】
- poj 2391(拆点 + 二分 + dinic)
- POJ 3281 Dining (dinic+拆点)
- POJ 3436 ACM Computer Factory(网络流 拆点)
- POJ 3436ACM Computer Factory 最大流+路径输出 dinic模板
- HDU4289(最大流)(dinic算法+拆点)
- hdu 2732 Leapin' Lizards(拆点dinic)
- 【POJ 3281 Dining】& 网络流Dinic & 拆点
- POJ 3308 Paratroopers (最小点权覆盖Dinic)
- 最大流dinic算法模板(链式前向星)
- UI知识点总结
- iOS测试
- php和html互相嵌入,不兼容的解决办法
- SQLSERVER获取两位的日期或月份
- Using ROS Navigation Package 实现导航
- POJ 3436 ACM Computer Factory(拆点+前向星dinic)||(拆点+邻接矩阵dinic)||(不拆点+dinic))
- Eclipse 的快捷键Ctrl+Shift+F 不起作用
- 设计模式读书笔记-----代理模式
- MindMapper内置浏览器如何进行使用
- 7. XSD 简易元素
- android 缓存工具类
- Linux Dan Dan~
- Activity的生命周期
- 设计模式读书笔记-----组合模式