题目链接: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. Sandworm Attack小结

    这个漏洞刚出来时就分析过,当时大致弄明白了原理,但对很多细节和原理还是一知半解.后来开始找工作……今天终于有时间来把欠的这部分功课补上. 这个漏洞网上的各种中英文分析已经很多了,因此这里我只根据自己的 ...

  2. sql2005 和 mysql 定时备份批处理

    保存为sqlbak.bat  目录我直接放winrar 的根目录了 或者拷贝一个winrar.exe 具体目录随意. 然后添加计划任务个人的话建议一周或者一天 虚拟主机等 建议每周或者每月 @echo ...

  3. RabbitMQ的事件总线

    RabbitMQ的事件总线 在上文中,我们讨论了事件处理器中对象生命周期的问题,在进入新的讨论之前,首先让我们总结一下,我们已经实现了哪些内容.下面的类图描述了我们已经实现的组件及其之间的关系,貌似系 ...

  4. github基本概念

    github: 托管项目代码. 仓库(repository):用来存放项目的代码,每个项目对应一个仓库,多个项目则有多个仓库. 收藏(star):收藏项目的人数.收藏别人的项目方便下次查看. 复制克隆 ...

  5. BZOJ1770:[USACO]lights 燈(高斯消元,DFS)

    Description 貝希和她的閨密們在她們的牛棚中玩遊戲.但是天不從人願,突然,牛棚的電源跳閘了,所有的燈都被關閉了.貝希是一個很膽小的女生,在伸手不見拇指的無盡的黑暗中,她感到驚恐,痛苦與絕望. ...

  6. Codeforces Round #527 (Div. 3) F. Tree with Maximum Cost 【DFS换根 || 树形dp】

    传送门:http://codeforces.com/contest/1092/problem/F F. Tree with Maximum Cost time limit per test 2 sec ...

  7. Linux学习总结(六)-su命令 sudo 命令 限制root远程登录

    root 用户拥有至高无上的权利,那么我们运维人员是不是直接在root用户下处理所有问题呢? 答案是否定的,权力越大,责任越大,人是会犯错的,因此我们要在不影响我们的工作情况下,尽量限制我们的权力,以 ...

  8. 移动端 Touch 事件

    在移动端页面开发时,常常会用到touch事件,比如左滑右滑的轮播等.常用的触摸事件有touchstart,touchmove,touchend. 每个事件包含下面三个用于跟踪虎摸的属性: touche ...

  9. maven 打包时动态替换properties资源文件中的配置值

    pom build节点下面添加resource配置: <resources> <resource> <directory>src/main/resources/&l ...

  10. Filter实现字符集统一设置

    Filter实现字符集统一设置 其实是对request和response请求进行了拦截 1.创建Filter类,实现javax.Servlet接口 doFilter方法 //设置字符集 request ...