POJ-3436 ACM Computer Factory---最大流+拆点
题目链接:
https://vjudge.net/problem/POJ-3436
题目大意:
每台电脑有p个组成部分,有n个工厂加工电脑。每个工厂对于进入工厂的半成品的每个组成部分都有要求,由p个数字描述,0代表这个部分不能有,1代表这个部分必须有,2代表这个部分的有无无所谓。每个工厂的产出也不尽相同,也是由p个数字代表,0代表这个部分不存在,1代表这个部分存在。每个工厂都有一个最大加工量。给出这n个工厂的以上数据,求出最多能加工出多少台电脑。
解题思路:
这道题主要是如何建设出网络出来,每个工厂表示一个点
1、首先对每个点进行拆分,拆成i(输入部分)和n+i(输出部分),之间连接一条边,权值为这个点的加工量(拆点这个技巧是为了维护点的权值)
2、对每个点的输入部分(i),如果没有一,那就从超级源点s出发,连一条边到该点,权值为这个点的加工量。(因为只有全是0,或者是0或2没有1,那才是整个工厂的出发点)(此处不要忘记2的存在,一开始只把全是0的和超级源点s建边,后来想到只要没有1,都可以建边)
3、对于每个点的输出部分(n + i),如果全是1,说明已经建好,和超级汇点建边,权值为这个点的加工量
4、对于每个点的输出部分(n + i),只要满足其他点的输入部分,这两点之间可以建立边,权值设置成INF(这里设置成INF的目的是为了最后输出答案中的边,便于寻找这些边,只要权值为INF的边且流量不为0,那么这条边就可以输出)
然后就是从源点s到汇点t的最大流(传送门:最大流模板)
#include<iostream>
#include<vector>
#include<cstring>
#include<queue>
using namespace std;
const int maxn = + ;
const int INF = 0x3f3f3f3f;
int n, m;
struct edge
{
int u, v, c, f;
edge(int u, int v, int c, int f):u(u), v(v), c(c), f(f){}
};
vector<edge>e;
vector<int>Map[maxn];
int a[maxn], p[maxn];
void init(int n)
{
e.clear();
for(int i = ; i <= n; i++)Map[i].clear();
}
void addedge(int u, int v, int c)
{
//cout<<u<<" "<<v<<" "<<c<<endl;
e.push_back(edge(u, v, c, ));
e.push_back(edge(v, u, , ));
int m = e.size();
Map[u].push_back(m - );
Map[v].push_back(m - );
}
int Maxflow(int s, int t)
{
int flow = ;
for(;;)
{
memset(a, , sizeof(a));
queue<int>q;
q.push(s);
a[s] =INF;
while(!q.empty())
{
int u = q.front();
q.pop();
for(int i = ; i < Map[u].size(); i++)
{
edge& now = e[Map[u][i]];
int v = now.v;
if(!a[v] && now.c > now.f)//还未流经并且边还有容量
{
p[v] = Map[u][i];
a[v] = min(a[u], now.c - now.f);
q.push(v);
}
}
if(a[t])break;//已经到达汇点
}
if(!a[t])break;//已经没有增广路
for(int u = t; u != s; u = e[p[u]].u)
{
e[p[u]].f += a[t];
e[p[u] ^ ].f -= a[t];
}
flow += a[t];
}
return flow;
}
int cnt[maxn][maxn];
vector<edge>ans;
int main()
{
cin >> m >> n;
for(int i = ; i <= n; i++)
{
for(int j = ; j <= * m; j++)cin >> cnt[i][j];
}
int s = , t = * n + ;
for(int i = ; i <= n; i++)
{
int tot1 = , tot2 = ;
for(int j = ; j <= m; j++)tot1 += cnt[i][j] == ? : ;//此处只要没有1,就可以和s建边
for(int j = m + ; j <= * m; j++)tot2 += cnt[i][j];//此处全为1就可以和t建边
addedge(i, i + n, cnt[i][]);
if(tot1 == )addedge(s, i, cnt[i][]);
if(tot2 == m)//和t建边之后没必要寻找其他点建边
{
addedge(i + n, t, cnt[i][]);
continue;
}
for(int j = ; j <= n; j++)
{
if(i == j)continue;
int flag = ;
for(int k = ; k <= m; k++)
{
if(cnt[j][k] == && cnt[i][m + k] != )//第j个点的第k个值为0,说明不需要第k个元件,那么第i个点的第k原件输出只能为0
{
flag = ;
break;
}
if(cnt[j][k] == && cnt[i][m + k] != )//第j个点的第k个值为1,说明需要第k个元件,那么第i个点的第k原件输出只能为1
{
flag = ;
break;
}
}
if(flag)addedge(i + n, j, INF);//ij可以建边,设置成INF
}
}
cout<<Maxflow(s, t)<<" ";
for(int i = ; i < e.size(); i += )//此处+=2,是因为最大流有反向边
{
//cout<<e[i].u<<" "<<e[i].v<<" "<<e[i].c<<" "<<e[i].f<<endl;
if(e[i].c == INF && e[i].f > )
{
ans.push_back(e[i]);
}
}
cout<<ans.size()<<endl;
for(int i = ; i < ans.size(); i++)
{
cout<<ans[i].u - n<<" "<<ans[i].v<<" "<<ans[i].f<<endl;
}
}
POJ-3436 ACM Computer Factory---最大流+拆点的更多相关文章
- POJ 3436 ACM Computer Factory 最大流,拆点 难度:1
题目 http://poj.org/problem?id=3436 题意 有一条生产线,生产的产品共有p个(p<=10)零件,生产线上共有n台(n<=50)机器,每台机器可以每小时加工Qi ...
- Poj 3436 ACM Computer Factory (最大流)
题目链接: Poj 3436 ACM Computer Factory 题目描述: n个工厂,每个工厂能把电脑s态转化为d态,每个电脑有p个部件,问整个工厂系统在每个小时内最多能加工多少台电脑? 解题 ...
- poj 3436 ACM Computer Factory 最大流+记录路径
题目 题意: 每一个机器有一个物品最大工作数量,还有一个对什么物品进行加工,加工后的物品是什么样.给你无限多个初始都是000....的机器,你需要找出来经过这些机器操作后最多有多少成功的机器(111. ...
- 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:http://poj.org/problem?id=3436 题意 组配计算机,每个机器的能力为x,只能处理一定条件的计算机,能输出特定的计算机配置.进去的要求有1,进来的计算机这个 ...
- POJ - 3436 ACM Computer Factory(最大流)
https://vjudge.net/problem/POJ-3436 题目描述: 正如你所知道的,ACM 竞赛中所有竞赛队伍使用的计算机必须是相同的,以保证参赛者在公平的环境下竞争.这就是所有这些 ...
- POJ 3436 ACM Computer Factory(最大流+路径输出)
http://poj.org/problem?id=3436 题意: 每台计算机包含P个部件,当所有这些部件都准备齐全后,计算机就组装完成了.计算机的生产过程通过N台不同的机器来完成,每台机器用它的性 ...
- 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 ...
随机推荐
- kuangbin专题16A(kmp模板)
题目链接: https://vjudge.net/contest/70325#problem/A 题意: 有两个数组 a, b, 输出 b 数组在 a 数组中的第一个匹配位置, 不能匹配则输出 -1. ...
- 利用CSS制作脸书
很多网站都支持图片上的头像框识别,鼠标在头像框处,会提示一些人物信息. 这次就利用CSS实现这样一个功能: div处主要包括两部分,一部分是图片:另一部分是链接以及脸框 <div class=& ...
- php接入图灵机器人
官网:http://www.tuling123.com 文档:https://www.kancloud.cn/turing/www-tuling123-com/718218 注册账号获取:apikey ...
- centos7虚拟机安装
Centos7 第1章 CENTOS 7 简介 1.1 centos的演变 启动流程sysvinit 串行启动:一次一个, 一个一个启动 并行启动:全部的一起启动 init优点 运行非常良好.主要依赖 ...
- APP请求超时问题-ios超时-android超时
最近发现公司的app在高峰期超时严重.用wifi网络一直超时,但qq等却正常.换成手机卡网络正常. 起初以为是DNS解析问题. 后来抓包,发现DNS解析正常,可以得到正确的A记录. 但tcp retr ...
- Windows开机自动登录及取消自动登录的设置
开机自动登录 1.开始菜单搜索框输入 “netplwiz” 按回车 或“Win+R”组合键打开“运行”框内输入“netplwiz” 或“运行”框内输入“control userpasswords2”( ...
- python3 no module named yaml
sudo apt-get install python3-yaml
- B - Reverse and Compare 小小思维题
http://agc019.contest.atcoder.jp/tasks/agc019_b 一开始的做法是, 用总数减去回文子串数目,因为回文子串怎么翻转都不影响答案. 然后,如果翻转afucka ...
- 深刻理解Linux进程间通信(IPC)
https://www.ibm.com/developerworks/cn/linux/l-ipc/ linux下进程间通信的几种主要手段简介: 管道(Pipe)及有名管道(named pipe):管 ...
- Linux Shell命令系列(4)
16. cat命令 “cat”代表了连结(Concatenation),连接两个或者更多文本文件或者以标准输出形式打印文件的内容. 17. cp 命令 “copy”就是复制.它会从一个地方复制一个文件 ...