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 ...
随机推荐
- SAS笔记(8) 利用数组重构SAS数据集
在实际应用中,我们经常会把宽数据(一个患者一条观测)转化为长数据(一个患者多条观测)或者将长数据(一个患者多条观测)转换为宽数据(一个患者一条观测),在R中我们可以利用Reshape2包来实现.在SA ...
- bzoj1227: [SDOI2009]虔诚的墓主人(树状数组,组合数)
传送门 首先,对于每一块墓地,如果上下左右各有$a,b,c,d$棵树,那么总的虔诚度就是$C_k^a*C_k^b*C_k^c*C_k^d$ 那么我们先把所有的点都给离散,然后按$x$为第一关键字,$y ...
- rlwrap: command not found和解决linux下sqlplus 提供浏览历史命令行的功能
rlwrap工具可以解决linux下sqlplus 提供浏览历史命令行的功能,和删除先前输入错误的字母等问题 1.安装 需要readline包 这个安装光盘就有 [root@asm RedHat]# ...
- SAP 权限层次
此文可是没有维护过权限的人对权限有一个整体的认知,转来加以记忆. 一是系统权限 主要是对模块为单位的权限划分,具体就是用户对该模块可见不可见,能不能对该模块进行再授权的操作.表现在用户界面就是用户登录 ...
- 清除input框对浏览器保存的用户名和密码自动填充问题
清除input框对浏览器保存的用户名和密码自动填充问题: type类型写如下写法,聚焦的时候type类型为“password” <input ng-model="getpwd" ...
- vue散碎知识点学习
1. vue散碎知识点学习 1.1. 特点 数据渲染/数据同步 组件化/模块化 其他功能路由,ajax,数据流 1.2. Vue.js学习资源 vuejs中文官网:http://cn.vuejs.or ...
- MD5-UTF8-大写加密
private string GetMD5Hash(string str) { string md5Str = ""; byte[] buffer = Encoding.UTF8. ...
- SerializeUtil
import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInpu ...
- 练习十三:水仙花数,用for循环实现
水仙花数是指一个n位正整数(n>=3),他得每个位上得数字得n次幂之和等于它本身(例如:1^3+5^3+3^3=153) for i in range(101,1000): #3位数得水仙花数 ...
- Windows Server 2016 安装Docker
使用Windows自带的Hyper-V 而不是安装Docker Enterprise. 废话不多说,撸起袖子开干 管理员权限打开PowerShell (因为server版本默认是cmd不是ps,所以需 ...