poj 3436 ACM Computer Factory 最大流+记录路径
题意:
每一个机器有一个物品最大工作数量,还有一个对什么物品进行加工,加工后的物品是什么样。给你无限多个初始都是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 最大流+记录路径的更多相关文章
- Poj 3436 ACM Computer Factory (最大流)
题目链接: Poj 3436 ACM Computer Factory 题目描述: n个工厂,每个工厂能把电脑s态转化为d态,每个电脑有p个部件,问整个工厂系统在每个小时内最多能加工多少台电脑? 解题 ...
- POJ 3436 ACM Computer Factory 最大流,拆点 难度:1
题目 http://poj.org/problem?id=3436 题意 有一条生产线,生产的产品共有p个(p<=10)零件,生产线上共有n台(n<=50)机器,每台机器可以每小时加工Qi ...
- POJ 3436 ACM Computer Factory (网络流,最大流)
POJ 3436 ACM Computer Factory (网络流,最大流) Description As you know, all the computers used for ACM cont ...
- POJ - 3436 ACM Computer Factory 网络流
POJ-3436:http://poj.org/problem?id=3436 题意 组配计算机,每个机器的能力为x,只能处理一定条件的计算机,能输出特定的计算机配置.进去的要求有1,进来的计算机这个 ...
- POJ - 3436 ACM Computer Factory(最大流)
https://vjudge.net/problem/POJ-3436 题目描述: 正如你所知道的,ACM 竞赛中所有竞赛队伍使用的计算机必须是相同的,以保证参赛者在公平的环境下竞争.这就是所有这些 ...
- POJ 3436 ACM Computer Factory(最大流+路径输出)
http://poj.org/problem?id=3436 题意: 每台计算机包含P个部件,当所有这些部件都准备齐全后,计算机就组装完成了.计算机的生产过程通过N台不同的机器来完成,每台机器用它的性 ...
- POJ 3436 ACM Computer Factory (拆点+输出解)
[题意]每台计算机由P个零件组成,工厂里有n台机器,每台机器针对P个零件有不同的输入输出规格,现在给出每台机器每小时的产量,问如何建立流水线(连接各机器)使得每小时生产的计算机最多. 网络流的建图真的 ...
- POJ 3436 ACM Computer Factory
题意: 为了追求ACM比赛的公平性,所有用作ACM比赛的电脑性能是一样的,而ACM董事会专门有一条生产线来生产这样的电脑,随着比赛规模的越来越大,生产线的生产能力不能满足需要,所以说ACM董事会想 ...
- 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 ...
随机推荐
- 经常使用的Sublime Text 快捷键
最常用的 Sublime快捷键:
- 【Linux】find查找空文件夹
linux下批量删除空文件(大小等于0的文件)的方法 find . -name "*" -type f -size 0c | xargs -n 1 rm -f 就是删除1k大小的文 ...
- 【Jboss】A RESOURCE POOL IS PERMANENTLY BROKEN!
jboss后台报错,其中有这个错误 [error] A RESOURCE POOL IS PERMANENTLY BROKEN! 查阅多方资料后发现.数据库连接配置文件中,有地方存在空格,导致服务连接 ...
- buuctf刷题之旅—web—WarmUp
启动靶机 查看源码发现source.php 代码审计,发现hint.php文件 查看hint.php文件(http://7ab330c8-616e-4fc3-9caa-99d9dd66e191.nod ...
- gears-绕过rbash
0x00 信息收集 0x01 smb攻击 crunch 生成密码的一个软件 @%%,这个是给的密码参数. crunch 4 4 -t @%%, -o words 最小4位,最长 4位 fcrackzi ...
- 【葵花宝典】lvs+keepalived部署kubernetes(k8s)高可用集群
一.部署环境 1.1 主机列表 主机名 Centos版本 ip docker version flannel version Keepalived version 主机配置 备注 lvs-keepal ...
- FI_F4_ZTERM付款条件代码
这个函数可以弹出一个选择帮助,返回一个付款条件代码 CALL FUNCTION 'FI_F4_ZTERM' EXPORTING I_KOART = 'K' " K为供应商,D为客户 * I_ ...
- Tensorflow-基础使用
Tensorflow基本概念 使用图(graphs)来表示计算任务 在被称之为会话(Session)的上下文(context)中执行图 使用tensor表示数据 通过变量(Variable)维护状态 ...
- JAVA高并发集合详解
Queue(队列)主要是为了高并发准备的容器Deque:双端队列,可以反方向装或者取 最开始jdk1.0只有Vector和hashtable 默认所有方法都实现了synchronized锁,线程安全但 ...
- Qt 使用tablib获取多媒体tag信息
最近项目需要, 要获取音乐文件tag信息. 有两个方式, 本人偏向第二种方式. 效率比较高,可控性比较好. 一.QML方式 使用QML Audio component 进行解析. 将多媒体文件都放到P ...