POJ-3436:ACM Computer Factory (Dinic最大流)
题目链接:http://poj.org/problem?id=3436
解题心得:
- 题目真的是超级复杂,但解出来就是一个网络流,建图稍显复杂。其实提炼出来就是一个工厂n个加工机器,每个机器有一个效率w,q个材料入口,q个材料出口,每个口有三个数表示状态,1表示一定有入/出的材料,0表示没有入/出的材料,2表示可能有入的材料。如果一个机器入口全是0,代表这是起始机器,如果一个机器出口全是1,那么代表这是末尾机器。
- 具体做法:
- 将每个机器i拆成两点i和i+n分别代表进和出
- 建立超级源点,连在起始机器上,流量INF。 建立超级汇点,找到末尾机器连在超级汇点上,流量INF。
- 一个机器拆成的两个点i和i+n连上,流量就是这个点的效率w。
- 然后暴力匹配,看一个点的所有出口是否可以完全对应一个点的入口,如果可以,匹配上,流量INF。
- 跑Dinic,得到最大流。
- 刚开始看到这个题没啥思路,因为关系太过于复杂,但是只要将题目中所有的关系提炼出来,就很容易建立一个网络图,要整体效率最大,那就是跑一个最大流啊,但是如果关系找漏GG。
#include <stdio.h>
#include <cstring>
#include <stdlib.h>
#include <queue>
#include <math.h>
#include <vector>
#include <climits>
using namespace std;
const int maxn = 1e4+;
const int INF = INT_MAX; int p, n, S, T, level[maxn], iter[maxn];
struct Machine {
int in[];
int out[];
int p;
}m[maxn]; struct Edge {
int to, cap, rev, flow;
Edge(int To, int Cap, int Rev, int Flow):
to(To), cap(Cap), rev(Rev), flow(Flow){}
}; vector <Edge> ve[maxn]; void add_edge(int s,int t, int cap) {//建边
ve[s].push_back(Edge(t, cap, ve[t].size(), ));
ve[t].push_back(Edge(s, , ve[s].size()-, ));
} void build_edge() {//找出口和入口的关系
for(int i=;i<=n;i++) {
for(int j=;j<=n;j++) {
if(i == j)
continue;
bool flag = false;
for(int k=;k<=p;k++) {
if(m[j].in[k] != && m[i].out[k] != m[j].in[k]) {
flag = true;
break;
}
}
if(!flag)
add_edge(i+n, j, INF);
}
add_edge(i, i+n, m[i].p);
}
} void init() {
scanf("%d%d",&p,&n);
S = , T = *n + ;
for(int i=;i<=n;i++) {//找起始机器和末尾机器
scanf("%d", &m[i].p);
bool flag = false;
for (int j = ; j <= p; j++) {
scanf("%d", &m[i].in[j]);
if (m[i].in[j] == )
flag = true;
}
if (!flag)
add_edge(S, i, INF);
flag = false;
for (int j = ; j <= p; j++) {
scanf("%d", &m[i].out[j]);
if (m[i].out[j] != )
flag = true;
}
if (!flag)
add_edge(i+n, T, INF);
}
build_edge();
} bool bfs() {
memset(level, -, sizeof(level));
level[S] = ;
queue <int> qu;
qu.push(S);
while(!qu.empty()) {
int now = qu.front(); qu.pop();
for(int i=; i<ve[now].size(); i++) {
Edge &e = ve[now][i];
if(e.cap > e.flow && level[e.to] < ) {
level[e.to] = level[now] + ;
qu.push(e.to);
}
}
}
return level[T] > ;
} int dfs(int now, int f) {
if(now == T) return f;
for(int &i=iter[now]; i<ve[now].size(); i++) {
Edge &e = ve[now][i];
if(e.cap > e.flow && level[e.to] > level[now]) {
int d = dfs(e.to, min(f, e.cap-e.flow));
if(d > ) {
e.flow += d;
ve[e.to][e.rev].flow -= d;
return d;
}
}
}
return ;
} int max_flow() {//Dinic跑最大流
int ans = ;
while(bfs()) {
int f = dfs(S, INF);
memset(iter, , sizeof(iter));
if(f > )
ans += f;
else
break;
}
return ans;
} int cnt, path[maxn][];
void Print_path(int ans) {//把路找出来
cnt = ;
for(int i=n+;i<=*n;i++) {
for(int j=;j<ve[i].size();j++) {
Edge &e = ve[i][j];
if(e.flow > && e.to <= n) {
path[cnt][] = i - n;
path[cnt][] = e.to;
path[cnt][] = e.flow;
cnt++;
}
}
}
printf("%d %d\n",ans, cnt);
for(int i=;i<cnt;i++)
printf("%d %d %d\n",path[i][], path[i][], path[i][]);
} int main() {
init();
int ans = max_flow();
Print_path(ans);
}
POJ-3436:ACM Computer Factory (Dinic最大流)的更多相关文章
- POJ 3436 ACM Computer Factory(最大流+路径输出)
http://poj.org/problem?id=3436 题意: 每台计算机包含P个部件,当所有这些部件都准备齐全后,计算机就组装完成了.计算机的生产过程通过N台不同的机器来完成,每台机器用它的性 ...
- POJ - 3436 ACM Computer Factory(最大流)
https://vjudge.net/problem/POJ-3436 题目描述: 正如你所知道的,ACM 竞赛中所有竞赛队伍使用的计算机必须是相同的,以保证参赛者在公平的环境下竞争.这就是所有这些 ...
- 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 ACM Computer Factory 题目描述: n个工厂,每个工厂能把电脑s态转化为d态,每个电脑有p个部件,问整个工厂系统在每个小时内最多能加工多少台电脑? 解题 ...
- POJ - 3436 ACM Computer Factory 网络流
POJ-3436:http://poj.org/problem?id=3436 题意 组配计算机,每个机器的能力为x,只能处理一定条件的计算机,能输出特定的计算机配置.进去的要求有1,进来的计算机这个 ...
- POJ 3436 ACM Computer Factory 最大流,拆点 难度:1
题目 http://poj.org/problem?id=3436 题意 有一条生产线,生产的产品共有p个(p<=10)零件,生产线上共有n台(n<=50)机器,每台机器可以每小时加工Qi ...
- poj 3436 ACM Computer Factory 最大流+记录路径
题目 题意: 每一个机器有一个物品最大工作数量,还有一个对什么物品进行加工,加工后的物品是什么样.给你无限多个初始都是000....的机器,你需要找出来经过这些机器操作后最多有多少成功的机器(111. ...
- 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 ...
随机推荐
- 最小生成树-Prim算法与Kruskal算法
一.最小生成树(MST) ①.生成树的代价:设G=(V,E)是一个无向连通网,生成树上各边的权值之和称为该生成树的代价. ②.最小生成树:在图G所有生成树中,代价最小的生成树称为最小生成树. 最小生成 ...
- a标签在实际工作中的应用
学习的时候,我们对a标签的认知: 1.href属性添加一个地址,可进行页面的跳转 2.用锚点,制作页面内跳转和跨页面跳转(之前有写过一篇关于锚点的随笔:http://www.cnblogs.com/q ...
- C/C++ 合法整数与字符
一.C语言中的合法整型 首先C语言中的整型有三种表示方式:十进制.八进制和十六进制.(C语言中没有表示二进制的整型) 十进制: 如 int a = 63; //一个正常的整型 八进制: 如果想用8进制 ...
- 最详细的Vue Hello World应用开发步骤
很多Vue的初学者想尝试这个框架时,都被webpack过于复杂的配置所吓倒,导致最后无法跑出一个期望的hello word效果.今天我就把我第一次使用webpack打包一个Vue Hello Worl ...
- c++新标准的一个问题
显示转换运算符存在多个兼容版本的时候,explicit 关键字无效,编译器默认会选择那个兼容版本进行转换,而不是报错. 测试环境:gcc4.8.1 示例代码: class plebe { privat ...
- Jenkins报错Caused: java.io.IOException: Cannot run program "sh" (in directory "D:\Jenkins\Jenkins_home\workspace\jmeter_test"): CreateProcess error=2, 系统找不到指定的文件。
想在本地执行我的python文件,我本地搭建了一个Jenkins,使用了execute shell来运行我的脚本,发现报错 [jmeter_test] $ sh -xe D:\tomcat\apach ...
- 如何遍历一个JSON对象的属性值???
当遇到一个JSON格式的对象时,不知道它有多少个属性,也不知道有什么属性,该如何遍历它的属性及其属性值呢??? 还是使用Java语言还是很像的,使用for语句. var obj = data[i]; ...
- Mac iTerm2使用总结
1.快捷键大全新建标签:command + t关闭标签:command + w切换标签:command + 数字 command + 左右方向键切换全屏:command + enter查找:comma ...
- Redis 有序聚合实现排行榜功能
排行榜功能是一个很普遍的需求.使用 Redis 中有序集合的特性来实现排行榜是又好又快的选择.Redis有序集合非常适用于有序不重复数据的存储 一般排行榜都是有实效性的,比如“用户积分榜”.如果没有实 ...
- 2018.09.23模拟总结(T2)
T1,T3我就不说啦,反正也不会.主要想讲的是T2. T2用了一个神奇的算法:折半搜索. 因为这个坑爹的数据范围告诉我们暴搜或是状压会TLE,而一半刚好能卡过去. 折半搜索其实跟暴搜没什么区别,就是折 ...