题目

题意:

每一个机器有一个物品最大工作数量,还有一个对什么物品进行加工,加工后的物品是什么样。给你无限多个初始都是000....的机器,你需要找出来经过这些机器操作后最多有多少成功的机器(111.....)

题解:

st是网络流起始点,en是终止点

首先肯定是要拆点的,因为题目上给出的是每一个机器的最大加工数量。这是对于机器本身,所以拆点之后i->start和i->last这条边的容量就是机器的最大加工数量

这个题的话建图很清晰,只要它要加工的原始物品是000...类型的,它就可以和st建一条边,容量无限大。如果加工后的物品是111...这种类型的,那么就可以让这个i->last和en建一条边,容量都是无限大

之后的话如果某个机器加工后的产品可以作为某个机器的原料,那就让他们之间连一条容量无限大的边。这里要注意,当某个机器接受的原料某个部件为2,那这个位置有没有部件都可以连边

例:1机器原料为1 2 1,那么1 0 1和1 1 1的产品他都可以接收

因为题目要求最后要输出那两个机器之间有流量,所以只要跑完最大流之后一个一个点的去检查。发现这个点和其他点之间有流量,那就出输出它.因为在跑最大流的过程中如果找到一条增广路,那么这条可行路上所有边的流量都要减少,就是通过这一点来判断的(具体看代码)

代码:

  1 #include <cstdio>
2 #include <algorithm>
3 #include <iostream>
4 #include <cstring>
5 #include <vector>
6 #include <queue>
7 #define INF 99999999
8 using namespace std;
9 const int N = 150;
10 int p,n,cnt;
11 int capacity[N],m[N][N],head[N],cur[N],d[N];
12
13 struct edge
14 {
15 int u,v,c,flow,next;
16 } e[N*N];
17 struct shudui
18 {
19 int u,v,w;
20 }que[N*N];
21 void adde(int u,int v,int w,int f)
22 {
23 e[cnt].v=v;
24 e[cnt].u=u;
25 e[cnt].c=w;
26 e[cnt].flow=f;
27 e[cnt].next=head[u];
28 head[u]=cnt++;
29 }
30 bool bfs(int s,int t)
31 {
32 for(int i=0; i<=2*n+2; i++) d[i]=0;
33 d[s]=1;
34 queue <int > q;
35 q.push(s);
36 while(!q.empty())
37 {
38 int u=q.front();
39 q.pop();
40 for(int i=head[u]; i!=-1; i=e[i].next)
41 {
42 int v=e[i].v;
43 if(!d[v] && e[i].c>e[i].flow)
44 {
45 d[v]=d[u]+1;
46 q.push(v);
47 }
48 }
49 }
50 return d[t]!=0;
51 }
52 int dfs(int s,int a)
53 {
54 if(s==2*n+1 || a==0) return a;
55 int flow = 0;
56 for(int &i=cur[s]; i!=-1; i=e[i].next)
57 {
58 int v=e[i].v,f;
59 if(d[v]!=d[s]+1) continue ;
60 f=dfs(v,min(a,e[i].c-e[i].flow));
61 if(f)
62 {
63 e[i].flow+=f;
64 e[i^1].flow-=f;
65 a-=f;
66 flow+=f;
67 if(a==0) break;
68 }
69 }
70 if(!flow) d[s]=-1;
71 return flow;
72 }
73 int main()
74 {
75 scanf("%d%d",&p,&n);
76 memset(head,-1,sizeof(head));
77 for(int i=1; i<=n; i++)
78 {
79 scanf("%d",&capacity[i]);
80 for(int j=1; j<=2*p; j++) scanf("%d",&m[i][j]);
81 }
82
83 for(int i=1; i<=n; i++)
84 {
85 adde(i,i+n,capacity[i],0);
86 adde(i+n,i,0,0);
87 int flag1=1,flag2=1;
88 for(int j=1; j<=p; j++)
89 {
90 if(m[i][j]==1) flag1=0;
91 if(m[i][j+p]!=1) flag2=0;
92 }
93 if(flag1) adde(0,i,INF,0),adde(i,0,0,0);
94 if(flag2) adde(i+n,2*n+1,INF,0),adde(2*n+1,i+n,0,0);
95 }
96 for(int i=1; i<=n; i++)
97 {
98 for(int j=1; j<=n; j++) //这里j的初始值不能是i+1,卧槽!!
99 {
100 if(i==j) continue ;
101 bool ok = true ;
102 for(int k=p+1; k<=p*2; k++)
103 {
104 int now = k-p;
105 if(m[j][now]==2) continue ;
106 if(m[i][k]!=m[j][now]) ok=false;
107 }
108 if(ok)
109 {
110 adde(i+n,j,INF,0);
111 adde(j,i+n,0,0);
112 }
113 }
114 }
115 int max_flow = 0;
116 while(bfs(0,2*n+1))
117 {
118 for(int i=0; i<=2*n+1; i++) cur[i]=head[i];
119 max_flow+=dfs(0,INF);
120 }
121 printf("%d ",max_flow);
122 int ans=0;
123 for(int i=1+n; i<=2*n; i++) //如果两个点之间有合作关系,那么他们的e[j].flow肯定不会为0,就是利用这一点找出来所有有合作关系的
124 { //点。题目没有要求怎么输出,那就随便输出就可以
125 for(int j=head[i]; j!=-1; j=e[j].next)
126 {
127 int v=e[j].v;
128 if(v!=2*n+1 && v!=0 && e[j].flow && v!=i-n)
129 {
130 que[ans].u=i-n;
131 que[ans].v=v;
132 que[ans].w=e[j].flow;
133 ans++;
134 }
135 }
136 }
137 printf("%d\n",ans);
138 for(int i=0;i<ans;++i)
139 {
140 printf("%d %d %d\n",que[i].u,que[i].v,que[i].w);
141 }
142 return 0;
143 }

poj 3436 ACM Computer Factory 最大流+记录路径的更多相关文章

  1. Poj 3436 ACM Computer Factory (最大流)

    题目链接: Poj 3436 ACM Computer Factory 题目描述: n个工厂,每个工厂能把电脑s态转化为d态,每个电脑有p个部件,问整个工厂系统在每个小时内最多能加工多少台电脑? 解题 ...

  2. POJ 3436 ACM Computer Factory 最大流,拆点 难度:1

    题目 http://poj.org/problem?id=3436 题意 有一条生产线,生产的产品共有p个(p<=10)零件,生产线上共有n台(n<=50)机器,每台机器可以每小时加工Qi ...

  3. POJ 3436 ACM Computer Factory (网络流,最大流)

    POJ 3436 ACM Computer Factory (网络流,最大流) Description As you know, all the computers used for ACM cont ...

  4. POJ - 3436 ACM Computer Factory 网络流

    POJ-3436:http://poj.org/problem?id=3436 题意 组配计算机,每个机器的能力为x,只能处理一定条件的计算机,能输出特定的计算机配置.进去的要求有1,进来的计算机这个 ...

  5. POJ - 3436 ACM Computer Factory(最大流)

    https://vjudge.net/problem/POJ-3436 题目描述:  正如你所知道的,ACM 竞赛中所有竞赛队伍使用的计算机必须是相同的,以保证参赛者在公平的环境下竞争.这就是所有这些 ...

  6. POJ 3436 ACM Computer Factory(最大流+路径输出)

    http://poj.org/problem?id=3436 题意: 每台计算机包含P个部件,当所有这些部件都准备齐全后,计算机就组装完成了.计算机的生产过程通过N台不同的机器来完成,每台机器用它的性 ...

  7. POJ 3436 ACM Computer Factory (拆点+输出解)

    [题意]每台计算机由P个零件组成,工厂里有n台机器,每台机器针对P个零件有不同的输入输出规格,现在给出每台机器每小时的产量,问如何建立流水线(连接各机器)使得每小时生产的计算机最多. 网络流的建图真的 ...

  8. POJ 3436 ACM Computer Factory

    题意:   为了追求ACM比赛的公平性,所有用作ACM比赛的电脑性能是一样的,而ACM董事会专门有一条生产线来生产这样的电脑,随着比赛规模的越来越大,生产线的生产能力不能满足需要,所以说ACM董事会想 ...

  9. kuangbin专题专题十一 网络流 POJ 3436 ACM Computer Factory

    题目链接:https://vjudge.net/problem/POJ-3436 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. 【译】Async/Await(二)——Futures

    原文标题:Async/Await 原文链接:https://os.phil-opp.com/async-await/#multitasking 公众号: Rust 碎碎念 翻译 by: Praying ...

  2. 跨站脚本漏洞(XSS)基础

    什么是跨站脚本攻击XSS 跨站脚本(cross site script),为了避免与样式css混淆所以简称为XSS,是一种经常出现在web应用中的计算机安全漏洞,也是web中最主流的攻击方式. 什么是 ...

  3. scp传文件夹

    scp -r /root/backupdb/2014-08-15(文件夹)    root@192.168.1.98:/root(目录)

  4. Cloudera Manager添加主机节点

    为了监控方便,想把研发环境中的主机节点都纳入Cloudera Manager的管理中,这样在遇到问题时可方便的查看主机的硬件资源情况. 添加主机节点有多种方式,由于我是离线工作,所以选择rpm包的方式 ...

  5. LeetCode349. 两个数组的交集

    题目 给定两个数组,编写一个函数来计算它们的交集. 分析 数组元素值可以很大,所以不适合直接开数组进行哈希,这里要学习另一种哈希方式:集合 集合有三种,区别见下面代码随想录的Carl大佬的表格,总结的 ...

  6. 关于安装版JDK1.8 1.7更改多个JDK环境变量 不生效

    配置maven(apache-maven-3.3.9)时提示异常:'mvn' 不是内部或外部命令,上网查找得知 它不支持jdk1.8,所以重新安装jdk1.7,后来就出现下面的问题 现象: 当使用安装 ...

  7. Java程序入门

    编写Java源程序 在d:\day01 目录下新建文本文件,完整的文件名修改为HelloWorld.java ,其中文件名为HelloWorld ,后缀名必须为.java . 用记事本打开 在文件中键 ...

  8. 阿里云VPC网络内网实例通过SNAT连接外网

    场景: 1.有多个ECS实例,其中A实例有公网IP,可以上外网 其它实例没有公网IP,不能上外网 2.所有实例在一个交换机,也就是一个网络(172.16.0.0/16) 实例 内网IP 外网IP A ...

  9. 采用Sharding-JDBC解决分库分表

    源码:Sharding-JDBC(分库分表) 一.Sharding-JDBC介绍 1,介绍 Sharding-JDBC是当当网研发的开源分布式数据库中间件,从 3.0 开始Sharding-JDBC被 ...

  10. postgres多知识点综合案例

    使用到的知识点: 1.使用with临时存储sql语句,格式[with as xxx(), as xxx2() ]以减少代码: 2.使用round()取小数点后几位: 3.使用to_char()将时间格 ...