题目链接: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. 图的存储结构(邻接矩阵与邻接表)及其C++实现

    一.图的定义 图是由顶点的有穷非空集合和顶点之间边的集合组成,通常表示为: G=(V,E) 其中:G表示一个图,V是图G中顶点的集合,E是图G中顶点之间边的集合. 注: 在线性表中,元素个数可以为零, ...

  2. SchemaSpy

    SchemaSpy https://github.com/schemaspy/schemaspy/releases https://sourceforge.net/projects/schemaspy ...

  3. hive 的一个小问题

    hive查询语句中如果包含中文,如like '%奥巴马%' ,并且所查hive表中的数据是utf-8的,可能会查不出正确结果. 原因可能是系统环境的LANG 设置不是utf-8,需要把环境变量LANG ...

  4. 利用Underscore求数组的交集、并集和差集

    1 数组交集函数——intersection 数组的交集是指包含多个数组中的共同元素的一个数组,求数组的交集就是找出给定数组中的共有元素. 下面实现一个求两个数组交集的函数. 判断数组是够包含指定值, ...

  5. 在一个jsp页面中引用另一个jsp文件的路径的问题

    为了提高代码的重用性,经常需要在一个jsp页面中引用另一个jsp文件的代码.关于引用时的路径的问题.下面只介绍动态引用的,我觉得静态引用的应该也一样. 相对路径: 一.在同一个文件夹下,a.jsp中引 ...

  6. bzoj1818 [Cqoi2010]内部白点

    Description 无限大正方形网格里有n个黑色的顶点,所有其他顶点都是白色的(网格的顶点即坐标为整数的点,又称整点).每秒钟,所有内部白点同时变黑,直到不存在内部白点为止.你的任务是统计最后网格 ...

  7. Linux 查看所有登录用户的操作历史

    在linux系统的环境下,不管是root用户还是其它的用户只有登陆系统后用进入操作我们都可以通过命令history来查看历史记录,可是假如一台服务器多人登陆,一天因为某人误操作了删除了重要的数据.这时 ...

  8. [USACO07OPEN]吃饭Dining

    嘟嘟嘟 这应该是网络流入门题之一了,跟教辅的组成这道题很像. 把每一只牛看成书,然后对牛拆点,因为每一只牛只要一份,食物和饮料分别看成练习册和答案. #include<cstdio> #i ...

  9. 使用 PHP Curl 做数据中转

    流程 收集头部信息 收集请求数据 转换头部信息为 CURL 头部请求格式 使用 Curl 进行转发 收集 HTTP 头信息 function getAllHeaders() { $headers = ...

  10. centos中java安装跟配置

    安装配置java环境 [root@JxateiLinux src]# Wget  http://download.oracle.com/otn-pub/java/jdk/8u161-b12/2f38c ...