poj3436 ACM Computer Factory
来源:互联网 发布:煎饼侠 知乎 编辑:程序博客网 时间:2024/05/22 00:28
链接:http://poj.org/problem?id=3436
题意:有N台机器,输入输出都有P种配件。
输入有0,1,2,三种状态,分别代表不需要该配件,需要该配件,该配件可有可无。
输出有0,1,两种状态,分别代表该配件没有产出,该配件产出。
只有当满足某台机器的输出满足某个机器的输入时,两台机器才是完成协作。
如果一台机器的所有输出为1,且满足了它的输入,则表示产出了一台电脑。
参考网上思路。
拆点法。
把每个机器拆成两个点(输入点和输出点),i和i+n
建图:
如果机器的输入中没有1存在,则与源点连边,边权为INF
如果机器的输出中只有1存在,则与汇点连边,边权为INF
机器自身输入点和输出点连边,权值为这台机器的performance,即Qi
如果一台机器的输出满足另一台机器的输入,则两天机器连边,边权为INF
构图老是参考网上的,自己也不想想,怎么办啊~~~~这样下去怎么会有长进啊啊啊啊啊啊啊啊
#include<cstdio>#include<cstring>#include<queue>#define MAXN 110#define MAXP 15#define INF 0x7fffffff#define MIN(a,b) a>b?b:ausing namespace std;int map[MAXN][MAXN],mach[MAXN]; //map构建图,mach存储Qiint in[MAXN][MAXP],out[MAXN][MAXP];//存储每个机器的输入输出的配件要求int ans;int dist[MAXN];int resa[2*MAXN],resb[2*MAXN],resp[2*MAXN];int st_in(int in[][MAXP],int p,int i){ int j; for(j=0;j<p;j++) if(in[i][j]==1) return 0;return 1;}int ed_out(int out[][MAXP],int p,int i){ int j; for(j=0;j<p;j++) if(out[i][j]!=1) return 0;return 1;}int out_in(int out[][MAXP],int in[][MAXP],int i,int j,int p){int m; for(m=0;m<p;m++)if((out[i][m]+in[j][m])==1)return 0;return 1;}int BFS(int st,int ed){int k,i; memset(dist,-1,sizeof(dist));dist[st]=0;queue<int> q;q.push(st);while(!q.empty()){ k=q.front();q.pop();for(i=0;i<=ed;i++){ if(map[k][i]>0&&dist[i]<0) { dist[i]=dist[k]+1; q.push(i); }}}if(dist[ed]>0)return 1;return 0;}int DFS(int x,int ed,int low){ int i,a;if(x==ed)return low;for(i=0;i<=ed;i++){ if(map[x][i]>0&&dist[i]==dist[x]+1&&(a=DFS(i,ed,MIN(low,map[x][i])))){ map[x][i]-=a; map[i][x]+=a; return a;}}return 0;}void Dinic(int st,int ed){int res;while(BFS(st,ed)){ while((res=DFS(st,ed,INF))) { ans+=res; }}return;}int main(){int p,n,i,j;int st,ed,cnt;while(scanf("%d%d",&p,&n)!=EOF){ memset(mach,0,sizeof(mach)); memset(map,0,sizeof(map)); memset(in,0,sizeof(in)); memset(out,0,sizeof(out)); st=0; //超级源点 ed=2*n+1; //超级汇点 for(i=1;i<=n;i++) { scanf("%d",&mach[i]); map[i][i+n]=mach[i]; //拆点,每个机器拆成输入点i和输出点i+n //输入点和输出点连边,权值为这台机器的performance,即Qi for(j=0;j<p;j++) scanf("%d",&in[i][j]); for(j=0;j<p;j++) scanf("%d",&out[i][j]); if(st_in(in,p,i)) //如果机器的输入中没有1存在,则与源点连边,边权为INF map[st][i]=INF; if(ed_out(out,p,i)) //如果机器的输出中只有1存在,则与汇点连边,边权为INF map[i+n][ed]=INF; } for(i=1;i<=n;i++) for(j=1;j<=n;j++) if(out_in(out,in,i,j,p)) //如果一台机器的输出满足另一台机器的输入,则两天机器连边,边权为INF map[i+n][j]=INF; ans=0; cnt=0; Dinic(st,ed); //用Dinic求最大流 printf("%d ",ans); for(i=1;i<=n;i++) //在除了源点和汇点所在的边内找connection for(j=1;j<=n;j++) { if(i!=j&&map[j][i+n]>0)//大于零的反向边就是我们要找的路径 { resa[cnt]=i; resb[cnt]=j; resp[cnt]=map[j][i+n]; cnt++; } } printf("%d\n",cnt); for(i=0;i<cnt;i++) printf("%d %d %d\n",resa[i],resb[i],resp[i]);} return 0;}
0 0
- poj3436 ACM Computer Factory
- poj3436-ACM Computer Factory
- POJ3436 ACM Computer Factory
- POJ3436 ACM Computer Factory
- poj3436 ACM Computer Factory
- poj3436 ACM Computer Factory
- POJ3436-ACM Computer Factory
- (最大流) poj3436 ACM Computer Factory
- POJ3436 ACM Computer Factory 【最大流】
- [POJ3436]ACM Computer Factory 做题笔记
- POJ3436 ACM Computer Factory【网络流】
- poj3436 ACM Computer Factory 拆点+网络流
- poj3436 ACM Computer Factory, 最大流,输出路径
- poj3436--ACM Computer Factory(最大流,拆点dinic)
- ACM Computer Factory poj3436(网络流-ek)
- POJ3436.ACM Computer Factory(ACM计算机工厂)——最大流+拆点
- POJ3436--ACM Computer Factory--拆点EK算法求最大流
- POJ3436 ACM Computer Factory(dinic最大流+统计不同弧上流量的变化)
- resin 配置多个实例
- CF 421D--Bug in code
- 单纯又饥渴的IT男程序员已经成为有心机的黑木耳们诱杀的对象了!
- HDU1240
- poj 1637 Sightseeing tour(混合图欧拉回路)
- poj3436 ACM Computer Factory
- 8259A--可编程中断控制器
- opencv2.4.8+vs2010+win7环境搭建问题集合
- UnicodeEncodeError: 'ascii' codec can't encode characters in position 26-35: ordinal not in range(12
- STL_Map用法详解
- JBPM流程实例(PV)Process Variables
- Ubuntu下使用Vi是方向键变乱码 退格键不能使用的解决方法
- openfire单独编译指定插件的方法
- SFML 2.1 开发之旅 1