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 ...
随机推荐
- Sandworm Attack小结
这个漏洞刚出来时就分析过,当时大致弄明白了原理,但对很多细节和原理还是一知半解.后来开始找工作……今天终于有时间来把欠的这部分功课补上. 这个漏洞网上的各种中英文分析已经很多了,因此这里我只根据自己的 ...
- sql2005 和 mysql 定时备份批处理
保存为sqlbak.bat 目录我直接放winrar 的根目录了 或者拷贝一个winrar.exe 具体目录随意. 然后添加计划任务个人的话建议一周或者一天 虚拟主机等 建议每周或者每月 @echo ...
- RabbitMQ的事件总线
RabbitMQ的事件总线 在上文中,我们讨论了事件处理器中对象生命周期的问题,在进入新的讨论之前,首先让我们总结一下,我们已经实现了哪些内容.下面的类图描述了我们已经实现的组件及其之间的关系,貌似系 ...
- github基本概念
github: 托管项目代码. 仓库(repository):用来存放项目的代码,每个项目对应一个仓库,多个项目则有多个仓库. 收藏(star):收藏项目的人数.收藏别人的项目方便下次查看. 复制克隆 ...
- BZOJ1770:[USACO]lights 燈(高斯消元,DFS)
Description 貝希和她的閨密們在她們的牛棚中玩遊戲.但是天不從人願,突然,牛棚的電源跳閘了,所有的燈都被關閉了.貝希是一個很膽小的女生,在伸手不見拇指的無盡的黑暗中,她感到驚恐,痛苦與絕望. ...
- 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 ...
- Linux学习总结(六)-su命令 sudo 命令 限制root远程登录
root 用户拥有至高无上的权利,那么我们运维人员是不是直接在root用户下处理所有问题呢? 答案是否定的,权力越大,责任越大,人是会犯错的,因此我们要在不影响我们的工作情况下,尽量限制我们的权力,以 ...
- 移动端 Touch 事件
在移动端页面开发时,常常会用到touch事件,比如左滑右滑的轮播等.常用的触摸事件有touchstart,touchmove,touchend. 每个事件包含下面三个用于跟踪虎摸的属性: touche ...
- maven 打包时动态替换properties资源文件中的配置值
pom build节点下面添加resource配置: <resources> <resource> <directory>src/main/resources/&l ...
- Filter实现字符集统一设置
Filter实现字符集统一设置 其实是对request和response请求进行了拦截 1.创建Filter类,实现javax.Servlet接口 doFilter方法 //设置字符集 request ...