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 ...
随机推荐
- D. Beautiful Array
题目:http://codeforces.com/contest/1155/problem/D 给你n,x,一个n个数的序列,你可以选择一段区间,区间的数都乘以x,然后求出最大字段和 竟然是很简单的d ...
- AIM Tech Round 5 (rated, Div. 1 + Div. 2) E(思维,构造)
#include<bits/stdc++.h>using namespace std;long long a[150007];long long ans[150007];int main( ...
- svn图标修复
https://blog.csdn.net/doubleface999/article/details/55798736 前一阵用上了win8,装了最新版本的Tortoise SVN,但发现文件夹和文 ...
- JSONObject,JSONArray,String,Map间的互转
引言 在平常的Web项目开发过程中,json和String.map是最常用的类型和返回结果集,其中也经常会涉及到之间的各种相互转换,下边就总结一下: 1.String转JSONObject ...
- POJ3696 The Luckiest Number 欧拉定理
昨天终于把欧拉定理的证明看明白了...于是兴冲冲地写了2道题,发现自己啥都不会qwq 题意:给定一个正整数L<=2E+9,求至少多少个8连在一起组成正整数是L的倍数. 这很有意思么... 首先, ...
- eclipse ctrl+h
之前我的eclipse使用ctrl + h 出现的总是Plug-in Search ,总是需要点那个小三角才能找到File Search ,深感使用不便, 修改方法:Window->Genera ...
- java里如何使用输入流和输出流实现读取本地文件里内容和写出到本地文件里
不多说,直接上干货! 第一种方法 PWDemo.java package zhouls.bigdata.DataFeatureSelection.filter; import java.io.File ...
- linux php 安装xdebug
我的环境是PHP 5.2.5,下载的xdebug是Xdebug v2.2.1 源码包 PHP 5.3.20用的是Xdebug v2.1.0 {版本一定要匹配} 下载地址为:http://xdebug ...
- 3年,阅读量100万+, Github Star 15000+
这两天突然发现,三年前在博客园写的一篇文章阅读量超过百万了,对,还是技术文章.这个让我蛮惊讶的,当时刚开始写这篇文章的时候,一周的阅读量也才两三千,随着时间慢慢的过去,在搜索引擎的加持下竟然超过了百万 ...
- 自己动手实现STL 03:内存基本处理工具(stl_uninitialized.h)
一.前言 前面两篇已经编写了内存配置器和建构解构工具函数.这里,就准备编写并介绍下内存基本处理工具函数.比如uninitialized_copy().uninitialized_copy和 unini ...