题目链接: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最大流)的更多相关文章

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

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

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

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

  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 ACM Computer Factory 题目描述: n个工厂,每个工厂能把电脑s态转化为d态,每个电脑有p个部件,问整个工厂系统在每个小时内最多能加工多少台电脑? 解题 ...

  5. POJ - 3436 ACM Computer Factory 网络流

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

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

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

  7. poj 3436 ACM Computer Factory 最大流+记录路径

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

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

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

  9. POJ 3436 ACM Computer Factory

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

  10. 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. 最小生成树-Prim算法与Kruskal算法

    一.最小生成树(MST) ①.生成树的代价:设G=(V,E)是一个无向连通网,生成树上各边的权值之和称为该生成树的代价. ②.最小生成树:在图G所有生成树中,代价最小的生成树称为最小生成树. 最小生成 ...

  2. a标签在实际工作中的应用

    学习的时候,我们对a标签的认知: 1.href属性添加一个地址,可进行页面的跳转 2.用锚点,制作页面内跳转和跨页面跳转(之前有写过一篇关于锚点的随笔:http://www.cnblogs.com/q ...

  3. C/C++ 合法整数与字符

    一.C语言中的合法整型 首先C语言中的整型有三种表示方式:十进制.八进制和十六进制.(C语言中没有表示二进制的整型) 十进制: 如 int a = 63; //一个正常的整型 八进制: 如果想用8进制 ...

  4. 最详细的Vue Hello World应用开发步骤

    很多Vue的初学者想尝试这个框架时,都被webpack过于复杂的配置所吓倒,导致最后无法跑出一个期望的hello word效果.今天我就把我第一次使用webpack打包一个Vue Hello Worl ...

  5. c++新标准的一个问题

    显示转换运算符存在多个兼容版本的时候,explicit 关键字无效,编译器默认会选择那个兼容版本进行转换,而不是报错. 测试环境:gcc4.8.1 示例代码: class plebe { privat ...

  6. 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 ...

  7. 如何遍历一个JSON对象的属性值???

    当遇到一个JSON格式的对象时,不知道它有多少个属性,也不知道有什么属性,该如何遍历它的属性及其属性值呢??? 还是使用Java语言还是很像的,使用for语句. var obj = data[i]; ...

  8. Mac iTerm2使用总结

    1.快捷键大全新建标签:command + t关闭标签:command + w切换标签:command + 数字 command + 左右方向键切换全屏:command + enter查找:comma ...

  9. Redis 有序聚合实现排行榜功能

    排行榜功能是一个很普遍的需求.使用 Redis 中有序集合的特性来实现排行榜是又好又快的选择.Redis有序集合非常适用于有序不重复数据的存储 一般排行榜都是有实效性的,比如“用户积分榜”.如果没有实 ...

  10. 2018.09.23模拟总结(T2)

    T1,T3我就不说啦,反正也不会.主要想讲的是T2. T2用了一个神奇的算法:折半搜索. 因为这个坑爹的数据范围告诉我们暴搜或是状压会TLE,而一半刚好能卡过去. 折半搜索其实跟暴搜没什么区别,就是折 ...