题意:

每个电脑需要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. html5 简介

    html5基于html.html dom.xhtml的新版本. 为html5建立的一些新规则: 基于html.dom.xhtml和javascript: 减少对外部插件的需求,比如flash: 更多取 ...

  2. C# PictureBox控件畫圖

    PictureBox的正方向: BitMap初始化: Bitmap bt = new Bitmap(Width,Height);      Graphics gdi = Graphics.FromIm ...

  3. 如何取消浏览器护眼色 Lodop打印图片有窗口颜色的边框

    Lodop打印图片出现了边框,然而通常情况下是没有边框的,由于Lodop是基于本机的ie进行解析的,和IE的设置有关.用户的电脑和习惯千差万别,有人喜欢给浏览器加上护眼色,而这一个行为可能导致Lodo ...

  4. Java基础总结(一)

    1:程序执行是有顺序的,如果没有流程控制语句,执行顺序是从上到下, 2:对象没有引用指向他的时候,jvm虚拟机就会在合适的时候去清理内存垃圾 3:对象的引用就相当于方向盘,操作对象 4:java8大基 ...

  5. MyBatis:传参

    MyBatis从入门到放弃二:传参 前言 我们在mapper.xml写sql,如果都是一个参数,则直接配置parameterType,那实际业务开发过程中多个参数如何处理呢? 从MyBatis API ...

  6. pdo连接的时候设置字符编码是这样的

    $pdo = new \PDO(..,..,..) $pdo->query('SET NAMES utf8mb4'); $pdo->exex('sql....');

  7. 隐藏SharePoint 2013 team sites里的follow按钮

    cls $featureid = 'a7a2793e-67cd-4dc1-9fd0-43f61581207a'$webapps = Get-spWebApplicationforeach($webap ...

  8. 一种使用emwin库函数导致hardfault的情况

    @2018-08-27 使用函数 WM_SendMessageNoPara(hWin_MainTask, WM_INIT_DIALOG),调试至此处进入hardfault,经查是由于hWin_Main ...

  9. 【转】CPU上下文切换的次数和时间(context switch)

    http://iamzhongyong.iteye.com/blog/1895728 什么是CPU上下文切换? 现在linux是大多基于抢占式,CPU给每个任务一定的服务时间,当时间片轮转的时候,需要 ...

  10. Python数据类型(数字和字符串)

    1.1 Number(数字) Python可以处理任意大的整数,包括负整数. 浮点数也就是小数,之所以称为浮点数,是因为按照科学记数法表示时,一个浮点数的小数点位置是可变的.,比如,\(1.23\ti ...