题意:

每个电脑需要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. js日期

    常用函數: 創建一個日期對象 var ss =new Date(): 獲取一周的天數: ss.getDay(); 獲取1970年1月1日到現在的毫秒數: getTime(): 設置具體的日期: set ...

  2. codeforces445A

    DZY Loves Chessboard CodeForces - 445A DZY 喜欢棋盘,他很享受棋盘上的游戏. 他有一个 n 行和 m 列的棋盘.棋盘上的某些单元格是坏的位置,其他的是好的位置 ...

  3. BZOJ3963 WF2011MachineWorks(动态规划+斜率优化+cdq分治)

    按卖出时间排序后,设f[i]为买下第i台机器后的当前最大收益,则显然有f[i]=max{f[j]+gj*(di-dj-1)+rj-pi},且若此值<0,应设为-inf以表示无法购买第i台机器. ...

  4. python3.5opencv3图像文字标注

    import cv2 cv2.namedWindow("mark", cv2.WINDOW_AUTOSIZE) image = cv2.imread("../images ...

  5. 【洛谷P1376】机器工厂

    题目大意:给定两个有 N 个数的序列 A,B,每个点有一个对应的权值,现需要计算答案的贡献:\(B[i]*min\{A[j]+s*(i-j),j\in[1,i] \}\) 的最小值. 题解:由于 B ...

  6. 初见mobX

    先看如下的代码 const {observable}= mobox; const {observer}=mobxReact; const {Component}=React; const appSta ...

  7. 使用photoshop以及markman进行快速重构页面的几个步骤

    先来几个photoshop打开psd图的标准动作. ctrl+,ctrl-,放大,缩小psd图的.查看字体大小看T等等. 想psd图出现刻度 你只需要"> 设置度量单位为像素之后,打开 ...

  8. pow log 与 (int)

    1.不能用%d输出double类型的数 double a1=5.3; double a2=1234.1234; double a3=3412341.12341234; double b1=1.5; d ...

  9. linux 空间释放,mysql数据库空间释放

    测试告急,服务器不行了.down了…… 1.linux如何查看磁盘剩余空间: [root@XXX~]# df -lhFilesystem        Size      Used      Avai ...

  10. ADO.NET连接字符串大全

    说明ADO.NET连接字符串:SQL Server,SQL Server 2005,ACCESS,Oracle,MySQL,Interbase,IBM DB2,Sybase,Informix,Ingr ...