题意:

每个电脑需要P个组成部分,现有N的机器,每个机器都可以对电脑进行加工,不过加工的前提是某些部分已经存在,加工后会增加某些部分。且在单位时间内,每个机器的加工都有一个最大加工容量,求能得到的最大的流量,并且输出流经的所有路径。

思路:

最大流,EK算法。先建图,这里用邻接矩阵能比较简洁,由于每个机器(点)有权值,所以拆点,中间由与其权值想等的边连接,然后两两匹配,看是否能构成边。

代码:

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int Max = ;
const int eMax = ;
const int inf = 0x3f3f3f3f; struct
{
int w, in[], out[];
}mac[Max]; struct
{
int v, ini_w, w, re, next;
}edge[eMax]; int p, n, max_flow, num,k, edgeHead[Max],que[Max], pre[Max];
bool vis[Max]; void addedge(int u, int v, int w)
{
edge[k].v = v;
edge[k].ini_w = edge[k].w = w;
edge[k].next = edgeHead[u];
edge[k].re = k+;
edgeHead[u] = k ++;
edge[k].v = u;
edge[k].ini_w = edge[k].w = ;
edge[k].next = edgeHead[v];
edge[k].re = k-;
edgeHead[v] = k ++;
} int bfs()
{
int head, tail, i, u, v;
memset(vis, , sizeof(vis));
head = tail = ;
que[tail ++] = ;
vis[] = true;
while(tail > head){
u = que[head ++];
for(i = edgeHead[u]; i != ; i = edge[i].next){
v = edge[i].v;
if(!vis[v] && edge[i].w){
pre[v] = i;
if(v == *n+) return true;
que[tail ++] = v;
vis[v] = true;
}
}
}
return false;
} void end()
{
int u, p, sum = inf;
for(u = *n+; u != ; u = edge[edge[p].re].v){
p = pre[u];
sum = min(sum, edge[p].w);
}
for(u = *n+; u != ; u = edge[edge[p].re].v){
p = pre[u];
edge[p].w -= sum;
edge[edge[p].re].w += sum;
}
max_flow += sum;
} int main()
{
int i, j, u, m;
bool flag;
cin>>p>>n;
for(k = , i = ; i <= n; i ++)
{
cin>>mac[i].w;
flag = true;
for(j = ; j < p; j ++)
{
cin>>mac[i].in[j];
if(mac[i].in[j] == ) flag = false; // 这里要注意,0020也可以连源点,与汇点不同!
}
if(flag) addedge(, i, inf);
flag = true;
for(j = ; j < p; j ++)
{
cin>>mac[i].out[j];
if(mac[i].out[j] != ) flag = false;
}
if(flag) addedge(n+i, *n+, inf);
}
for(i = ; i <= n; i ++)
{
addedge(i, n+i, mac[i].w); // 拆点。
for(j = ; j <= n; j ++)
{
if(i == j) continue;
flag = true;
for(m = ; m < p; m ++)
if(mac[j].in[m] != && mac[j].in[m] != mac[i].out[m])
{
flag = false;
break;
}
if(flag) addedge(n+i, j, inf);
}
}
max_flow = , num = ;
while(bfs()) end();
for(u = n+; u < *n+ ; u ++) // 流经路径的输出,用邻接矩阵会更简洁。
for(i = edgeHead[u]; i != ; i = edge[i].next)
if(edge[i].v > && edge[i].v <= n && edge[i].ini_w > edge[i].w)
num ++;
cout<<max_flow<<" "<<num<<endl;
for(u = n+; u < *n+ ; u ++)
for(i = edgeHead[u]; i != ; i = edge[i].next)
if(edge[i].v > && edge[i].v <= n && edge[i].ini_w > edge[i].w)
cout<<u-n<<" "<<edge[i].v<<" "<<edge[i].ini_w - edge[i].w<<endl;
return ;
}

POJ3436 ACM Computer Factory【EK算法】的更多相关文章

  1. POJ3436 ACM Computer Factory —— 最大流

    题目链接:https://vjudge.net/problem/POJ-3436 ACM Computer Factory Time Limit: 1000MS   Memory Limit: 655 ...

  2. POJ-3436 ACM Computer Factory(网络流EK)

    As you know, all the computers used for ACM contests must be identical, so the participants compete ...

  3. POJ3436 ACM Computer Factory 【最大流】

    ACM Computer Factory Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5412   Accepted: 1 ...

  4. poj3436 ACM Computer Factory, 最大流,输出路径

    POJ 3436 ACM Computer Factory 电脑公司生产电脑有N个机器.每一个机器单位时间产量为Qi. 电脑由P个部件组成,每一个机器工作时仅仅能把有某些部件的半成品电脑(或什么都没有 ...

  5. POJ3436 ACM Computer Factory(最大流/Dinic)题解

    ACM Computer Factory Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8944   Accepted: 3 ...

  6. poj-3436.ACM Computer Factory(最大流 + 多源多汇 + 结点容量 + 路径打印 + 流量统计)

    ACM Computer Factory Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10940   Accepted:  ...

  7. POJ3436 ACM Computer Factory(最大流)

    题目链接. 分析: 题意很难懂. 大体是这样的:给每个点的具体情况,1.容量 2.进入状态 3.出去状态.求最大流. 因为有很多点,所以如果一个点的出去状态满足另一个点的进入状态,则这两个点可以连一条 ...

  8. POJ-3436 ACM Computer Factory 最大流 为何拆点

    题目链接:https://cn.vjudge.net/problem/POJ-3436 题意 懒得翻,找了个题意. 流水线上有N台机器装电脑,电脑有P个部件,每台机器有三个参数,产量,输入规格,输出规 ...

  9. POJ-3436:ACM Computer Factory (Dinic最大流)

    题目链接:http://poj.org/problem?id=3436 解题心得: 题目真的是超级复杂,但解出来就是一个网络流,建图稍显复杂.其实提炼出来就是一个工厂n个加工机器,每个机器有一个效率w ...

随机推荐

  1. linux中内存使用原理

    首先介绍一下linux中内存是如何使用的. 当有应用需要读写磁盘数据时,由系统把相关数据从磁盘读取到内存,如果物理内存不够,则把内存中的部分数据导入到磁盘,从而把磁盘的部分空间当作虚拟内存 来使用,也 ...

  2. redis map存储的注意点

  3. mysql5.7 rpm安装教程

    注意版本和此次更新时间 2017-12-03  版本:mysql-5.7.20-1.el6.x86_64  环境:linux6.x ​官方下载地址: wget https://dev.mysql.co ...

  4. Network POJ - 3694 (连通图标求桥)

    有上述两个数组定义可知:对于某点root,其有一儿子v,则有: 1.     如果dfn[root]<=low[v]此点是割点(对于dfs树的根,即最初节点需要两个儿子才是割点) 2.      ...

  5. Codeforces Round #431 (Div. 2) B. Tell Your World

    B. Tell Your World time limit per test 1 second memory limit per test 256 megabytes input standard i ...

  6. harmakik

    Solution 对于原树一个节点\(x\): \(f_x(h)\)表示,\(x\)作为一个深度为\(h\)的点时,\(x\)及其子树的安排方案有多少(不考虑\(x\)具体在深度为\(h\)的哪个点) ...

  7. luogu3385 负环 (spfa)

    我在做spfa的时候,如果有一个点被更新了超过N次,证明这个图里是有负环的. (神TM输出YE5和N0) #include<bits/stdc++.h> #define pa pair&l ...

  8. wechat 网页版通信全过程

    想要记录总结一下自己在这个小项目中所遇到的坑,以及解决问题的思路. 首先我觉得这个小项目挺有实际市场的,市场上有一定的需求量,这个就是驱动力吧.这个小项目的关键点是wechat网页版通信全过程,讲真挺 ...

  9. SqlServer存储过程详解

    SqlServer存储过程详解 1.创建存储过程的基本语法模板: if (exists (select * from sys.objects where name = 'pro_name')) dro ...

  10. Ubuntu安装Atom编辑器

    安装方法 执行以下命令 sudo add-apt-repository ppa:webupd8team/atom sudo apt-get update udo apt-get install ato ...