http://poj.org/problem?id=3436

题意:题意很难懂。给出P N。接下来N行代表N个机器,每一行有2*P+1个数字

第一个数代表容量,第2~P+1个数代表输入,第P+2到2*P+1是代表输出

输入有三种情况,0,1,2.输出有0,1两种情况
输入0代表不能有这个接口,1代表必须要有这个接口,2代表这个接口可有可无。
输出0代表有这个接口,1代表没有这个接口。大概输出就是像插头,输入像插座,只有接口吻合才可以相连。

思路:比较简单的最大流,主要是理解题意很难,把每台机器拆成输入和输出两个点,之间的流量就是第一个数那个流量,然后把符合题意的输入和超级源点相连,把符合题意的输出和超级汇点相连,把符合题意的机器之间的输入输出相连,流量都是INF,用ISAP找到增广路更新的时候,可以顺便记录路径。也可以最后和初始流量比较,如果减少了就说明有流量经过。可是ISAP模板错了导致一直WA了好久,以为是思路错了,用Dinic做过了,这里重新找了份鸟神的模板Orz。

Dinic:

 #include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
#define N 400
const int INF = 0x3f3f3f3f; struct Edge {
int u, v, cap, init;
Edge () {}
Edge (int u, int v, int cap, int init) : u(u), v(v), cap(cap), init(init) {}
}edge[N];
vector<int> G[N];
int cur[N], dis[N], gap[N], pre[N], tot, S, T;
int mp[N][N], info[N][N]; void Add(int u, int v, int cap) {
edge[tot] = Edge(u, v, cap, cap);
G[u].push_back(tot++);
edge[tot] = Edge(v, u, , );
G[v].push_back(tot++);
} int BFS() {
queue<int> que;
while(!que.empty()) que.pop();
memset(dis, INF, sizeof(dis));
dis[S] = ; que.push(S);
while(!que.empty()) {
int u = que.front(); que.pop();
for(int i = ; i < G[u].size(); i++) {
Edge& e = edge[G[u][i]];
if(dis[e.v] == INF && e.cap > ) {
dis[e.v] = dis[u] + ;
que.push(e.v);
}
}
}
return dis[T] < INF;
} int DFS(int u, int maxflow) {
if(u == T) return maxflow;
for(int i = cur[u]; i < G[u].size(); i++) {
cur[u] = i; Edge& e = edge[G[u][i]];
if(dis[e.v] == dis[u] + && e.cap > ) {
int flow = DFS(e.v, min(maxflow, e.cap));
if(flow > ) {
e.cap -= flow;
edge[G[u][i] ^ ].cap += flow;
return flow;
}
}
}
return ;
} int Dinic() {
int ans = ;
while(BFS()) {
memset(cur, , sizeof(cur));
int flow;
while(flow = DFS(S, INF)) ans += flow;
}
return ans;
} int main() {
int P, n;
while(~scanf("%d%d", &P, &n)) {
tot = ; S = , T = * n + ;
for(int i = S; i <= T; i++) G[i].clear();
memset(mp, , sizeof(mp));
for(int i = ; i <= n; i++) {
scanf("%d", &info[i][]);
for(int j = ; j <= P; j++)
scanf("%d", &info[i][j]);
for(int j = ; j <= P; j++)
scanf("%d", &info[i][j+P]);
}
for(int i = ; i <= n; i++) {
Add(i, i + n, info[i][]);
int fs = , ft = ;
for(int j = ; j <= P; j++) {
if(info[i][j] == ) fs = ;
if(info[i][j+P] == ) ft = ;
}
if(fs) Add(S, i, INF);
if(ft) Add(i + n, T, INF);
for(int j = ; j <= n; j++) {
if(i == j) continue;
fs = ;
for(int k = ; k <= P; k++)
if(info[i][k+P] != info[j][k] && info[j][k] != )
fs = ;
if(fs) Add(i + n, j, INF);
}
}
int ans = Dinic(), cnt = ;
for(int u = n + ; u <= * n; u++) {
for(int j = ; j < G[u].size(); j++) {
Edge& e = edge[G[u][j]];
if(e.v <= n && e.v > && e.cap < e.init) mp[u-n][e.v] += e.init - e.cap;
}
}
for(int i = ; i <= n; i++) {
for(int j = ; j <= n; j++) {
if(mp[i][j]) cnt++;
}
}
printf("%d %d\n", ans, cnt);
for(int i = ; i <= n; i++) {
for(int j = ; j <= n; j++) {
if(mp[i][j]) printf("%d %d %d\n", i, j, mp[i][j]);
}
}
}
return ;
}

ISAP:

 #include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
#define N 400
const int INF = 0x3f3f3f3f; struct Edge {
int v, nxt, cap, init;
}edge[N];
int cur[N], dis[N], gap[N], pre[N], head[N], tot, S, T;
int mp[N][N], info[N][N]; void Add(int u, int v, int cap) {
edge[tot].nxt = head[u]; edge[tot].v = v; edge[tot].cap = cap; edge[tot].init = cap; head[u] = tot++;
edge[tot].nxt = head[v]; edge[tot].v = u; edge[tot].cap = ; edge[tot].init = ; head[v] = tot++;
} int BFS() {
queue<int> que;
while(!que.empty()) que.pop();
memset(dis, -, sizeof(dis));
memset(gap, , sizeof(gap));
que.push(T); dis[T] = ;
gap[] = ;
while(!que.empty()) {
int u = que.front(); que.pop();
for(int i = head[u]; ~i; i = edge[i].nxt) {
int v = edge[i].v;
if(~dis[v]) continue;
dis[v] = dis[u] + ;
gap[dis[v]]++;
que.push(v);
}
}
return ~dis[S];
} int ISAP(int n, int m) { // n = T + 1 !!!
memcpy(cur, head, sizeof(cur));
int ans = , i, u = pre[S] = S;
while(dis[S] < n) {
if(u == T) {
int flow = INF, index = S;
for(i = S; i != T; i = edge[cur[i]].v) {
if(flow > edge[cur[i]].cap) {
flow = edge[cur[i]].cap; index = i;
}
}
for(i = S; i != T; i = edge[cur[i]].v) {
edge[cur[i]].cap -= flow; edge[cur[i]^].cap += flow;
int v = edge[cur[i]].v;
if(i > m && v > S && v <= m) {
mp[i-m][v] += flow;
}
}
ans += flow;
u = index;
}
for(i = cur[u]; ~i; i = edge[i].nxt)
if(edge[i].cap > && dis[edge[i].v] + == dis[u])
break;
if(~i) {
cur[u] = i;
pre[edge[i].v] = u;
u = edge[i].v;
} else {
if(--gap[dis[u]] == ) break;
int md = n;
for(i = head[u]; ~i; i = edge[i].nxt) {
if(dis[edge[i].v] < md && edge[i].cap > ) {
md = dis[edge[i].v]; cur[u] = i;
}
}
++gap[dis[u] = md + ];
u = pre[u];
}
}
return ans;
} int main() {
int n, P;
while(~scanf("%d%d", &P ,&n)) {
memset(head, -, sizeof(head));
memset(mp, , sizeof(mp));
tot = ; S = ; T = * n + ;
for(int i = ; i <= n; i++) {
scanf("%d", &info[i][]);
for(int j = ; j <= P; j++)
scanf("%d", &info[i][j]);
for(int j = ; j <= P; j++)
scanf("%d", &info[i][j+P]);
}
for(int i = ; i <= n; i++) {
Add(i, i + n, info[i][]);
int fs = , ft = ;
for(int j = ; j <= P; j++) {
if(info[i][j+P] == ) ft = ;
if(info[i][j] == ) fs = ;
}
if(fs) Add(S, i, INF);
if(ft) Add(i + n, T, INF);
for(int j = ; j <= n; j++) {
fs = ;
for(int k = ; k <= P; k++)
if(info[j][k] != && info[j][k] != info[i][k+P]) fs = ;
if(fs) Add(i + n, j, INF);
}
}
int ans = ISAP(T + , n), cnt = ;
// for(int i = n + 1; i <= 2 * n; i++) {
// for(int j = head[i]; ~j; j = edge[j].nxt) {
// int v = edge[j].v;
// if(v > 0 && v <= n && edge[j].cap < edge[j].init) mp[i-n][v] += edge[j].init - edge[j].cap;
// }
// }
for(int i = ; i <= n; i++)
for(int j = ; j <= n; j++)
if(mp[i][j]) cnt++;
printf("%d %d\n", ans, cnt);
for(int i = ; i <= n; i++)
for(int j = ; j <= n; j++)
if(mp[i][j]) printf("%d %d %d\n", i, j, mp[i][j]);
}
return ;
}

POJ 3436:ACM Computer Factory(最大流记录路径)的更多相关文章

  1. poj 3436 ACM Computer Factory 最大流+记录路径

    题目 题意: 每一个机器有一个物品最大工作数量,还有一个对什么物品进行加工,加工后的物品是什么样.给你无限多个初始都是000....的机器,你需要找出来经过这些机器操作后最多有多少成功的机器(111. ...

  2. Poj 3436 ACM Computer Factory (最大流)

    题目链接: Poj 3436 ACM Computer Factory 题目描述: n个工厂,每个工厂能把电脑s态转化为d态,每个电脑有p个部件,问整个工厂系统在每个小时内最多能加工多少台电脑? 解题 ...

  3. POJ 3436 ACM Computer Factory 最大流,拆点 难度:1

    题目 http://poj.org/problem?id=3436 题意 有一条生产线,生产的产品共有p个(p<=10)零件,生产线上共有n台(n<=50)机器,每台机器可以每小时加工Qi ...

  4. POJ 3436 ACM Computer Factory (网络流,最大流)

    POJ 3436 ACM Computer Factory (网络流,最大流) Description As you know, all the computers used for ACM cont ...

  5. POJ - 3436 ACM Computer Factory 网络流

    POJ-3436:http://poj.org/problem?id=3436 题意 组配计算机,每个机器的能力为x,只能处理一定条件的计算机,能输出特定的计算机配置.进去的要求有1,进来的计算机这个 ...

  6. POJ - 3436 ACM Computer Factory(最大流)

    https://vjudge.net/problem/POJ-3436 题目描述:  正如你所知道的,ACM 竞赛中所有竞赛队伍使用的计算机必须是相同的,以保证参赛者在公平的环境下竞争.这就是所有这些 ...

  7. POJ 3436 ACM Computer Factory(最大流+路径输出)

    http://poj.org/problem?id=3436 题意: 每台计算机包含P个部件,当所有这些部件都准备齐全后,计算机就组装完成了.计算机的生产过程通过N台不同的机器来完成,每台机器用它的性 ...

  8. POJ 3436 ACM Computer Factory (拆点+输出解)

    [题意]每台计算机由P个零件组成,工厂里有n台机器,每台机器针对P个零件有不同的输入输出规格,现在给出每台机器每小时的产量,问如何建立流水线(连接各机器)使得每小时生产的计算机最多. 网络流的建图真的 ...

  9. POJ 3436 ACM Computer Factory

    题意:   为了追求ACM比赛的公平性,所有用作ACM比赛的电脑性能是一样的,而ACM董事会专门有一条生产线来生产这样的电脑,随着比赛规模的越来越大,生产线的生产能力不能满足需要,所以说ACM董事会想 ...

  10. 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 ...

随机推荐

  1. Linux_Shell

    一.Shell 种类与归属 Unix与Linux常见的Shell脚本解释器有bash,sh,csh,ksh等(PS: bash 完全兼容sh) bash : linux 默认的shell sh : u ...

  2. 使用dbms_crypto包加密关键列数据

    对于业务系统中常见的需要加密的列我们可以在应用层来实现,也可以在数据库层实现,自己验证了一下使用dbms_crypto包来封装函数实现关键列的加密. 1.数据库版本 SQL> select * ...

  3. 满足要求的最长上升子序列(nlogn)

    题意:数列A1,A2,...,AN,修改最少的数字,使得数列严格单调递增.(1<=N<=10^5; 1<=Ai<=10^9 ) 思路:首先要明白的一点是数列是严格单调递增,那么 ...

  4. 4_STL设计理念_算法

    STL算法,容器,迭代器的设计理念1.STL容器通过 类模板 技术,实现 数据类型 和 容器模型的分离:2.迭代器技术 实现了 遍历和操作容器的统一方法3.STL算法设计理念:通过预定义的函数对象和函 ...

  5. NYOJ-组合数

    #include <stdio.h> #include <malloc.h> int main() { ; ]; scanf("%d%d", &n, ...

  6. python 处理文件夹中的文件(新建另一个文件保存),listdir顺序输出

    1.原始文件

  7. Otsu algorithm

    一.介绍 OTSU算法也称最大类间差法,有时也称之为大津算法,被认为是图像分割中阈值选取的最佳算法,计算简单,不受图像亮度和对比度的影响,因此在数字图像处理上得到了广泛的应用.它是按图像的灰度特性,将 ...

  8. Run P4 without P4factory - A Simple Example In Tutorials. -2 附 simple_router源码

    /* Copyright 2013-present Barefoot Networks, Inc. Licensed under the Apache License, Version 2.0 (th ...

  9. LoadRunner,一个简单的例子

    一.录制脚本,这个就不说了,但是可以说说录完一个简单的脚本之后可以做的一些后续工作 1.设置事务的开始跟结束点(参考他人的http://www.cnblogs.com/fnng/archive/201 ...

  10. C#中的泛型 【转】

    C#中的泛型 泛型(generic)是C#语言2.0和通用语言运行时(CLR)的一个新特性.泛型为.NET框架引入了类型参数(type parameters)的概念.类型参数使得设计类和方法时,不必确 ...