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. jquery实现获取手机验证码倒计时效果

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  2. c#中enum的用法小结

    转自:http://blog.csdn.net/moxiaomomo/article/details/8056356 enums枚举是值类型,数据直接存储在栈中,而不是使用引用和真实数据的隔离方式来存 ...

  3. 前端相关js

    1. mailchimp.js: 通过电子邮件订阅 RSS 的在线工具 2. ga.js:google推出的用来统计网站信息的一个java脚本.可以在GoogleAnalytics获得网站的统计和追踪 ...

  4. Distinct删除重复数据时 自定义的方法比较【转】

    最近项目中在用Linq Distinct想要将重复的资料去除时,发现它跟Any之类的方法有点不太一样,不能很直觉的在呼叫时直接带入重复数据判断的处理逻辑,所以当我们要用某个成员属性做重复数据的判断时, ...

  5. $_POST 变量以及$GLOBALS['HTTP_RAW_POST_DATA']

    $_POST 变量是一个数组,内容是由 HTTP POST 方法发送的变量名称和值. $_POST 变量用于收集来自 method="post" 的表单中的值.从带有 POST 方 ...

  6. Linux启动过程

    系统BIOS是当你点击开机键是第一个运行的程序.1. 首先主板需要接收到一个稳定的电源供给信号.如果没有得到稳定的电源供给系统自动关闭.2. 当接受到一个稳定的电源供给信号,处理器会启动,当处理器启动 ...

  7. alpha发布之小组评论

    在alpha发布之后,让我看到了,大家都很努力,在alpha发布前大家都尽量完成自己的项目,虽然大家都很忙,但是,都在抽出时间趟黑起早的完成项目,在你们身上有很多很值得我学习的地方,虽然我认为半夜睡觉 ...

  8. BizTalk开发系列(二) "Hello World" 程序搬运文件

    我们在<QuickLearn BizTalk系列之"Hello World">里讲到了如何快速的开发第一个BizTalk 应用程序.现在我们来讲一下如何把这个程序改成用 ...

  9. 类似网易新闻 title栏 滚动时 文字放大&变色

    http://files.cnblogs.com/files/n1ckyxu/ScrollTitleView.zip

  10. CentOS7配置日志(VirtualBox)

    版本为CentOS-Minimal 1.VirtualBox下安装CentOS. 新建虚拟机 下载CentOS,放入盘片,启动虚拟机,按提示开始安装(建议内存1G,硬盘10G以上)   2. 设置网络 ...