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 ...
随机推荐
- Error mounting / dev / sdb1 in Ubuntu
Uncommon users of Ubuntu OS, when connecting USB with NTFS file system, can observe the error: " ...
- 在mac上使用sublime text3搭建opencv3开发环境
安装sublime text3 打开mac终端,安装brew 安装opencv3,终端输入下面的coomand: brew install opencv@3 注意:@3表示安装的版本,如果不加@3,那 ...
- Jmeter-返回值乱码处理
Jmeter安装目录/bin/jmeter.properties中sampleresult.default.encoding默认为ISO-8859-1,将参数修改为 sampleresult.defa ...
- Tomcat服务器介绍及配置
一.Tomcat简介 Tomcat(Apache)是当前应用最广的JavaWeb服务器 1.Tomcat版本: 安装版:需要安装,一般不考虑使用.一个电脑只能安装一个,卸载也比较麻烦! 解压版: 直接 ...
- postgres_fdw
create extension postgres_fdw; --创建扩展 create server db0 foreign data wrapper postgres_fdw OPTIONS (h ...
- POJ1028 Web Navigation
题目来源:http://poj.org/problem?id=1028 题目大意: 模拟实现一个浏览器的“前进”和“回退”功能.由一个forward stack和一个backward stack实现. ...
- Linux系统下强制其他用户下线
强制其他用户下线命令格式:pkill -kill -t tty 解释: pkill -kill -t 强制其他用户下线命令 tty 强制其他用户下线的TTY 如上强制其他用户下线的命令为: pkill ...
- 判断是pc端登录还是移动端登录
java判断 https://blog.csdn.net/qq_32657581/article/details/71405838 https://zhidao.baidu.com/question/ ...
- Spring对数据库的操作
Spring结合Hibernate HibernateTemplate http://www.jb51.net/article/41541.htm //////// ...
- JS——json、ajax、jsonp
json: data.json: { "code":1, "data": { "name": "kid", " ...