POJ 3436:ACM Computer Factory(最大流记录路径)
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(最大流记录路径)的更多相关文章
- poj 3436 ACM Computer Factory 最大流+记录路径
题目 题意: 每一个机器有一个物品最大工作数量,还有一个对什么物品进行加工,加工后的物品是什么样.给你无限多个初始都是000....的机器,你需要找出来经过这些机器操作后最多有多少成功的机器(111. ...
- Poj 3436 ACM Computer Factory (最大流)
题目链接: Poj 3436 ACM Computer Factory 题目描述: n个工厂,每个工厂能把电脑s态转化为d态,每个电脑有p个部件,问整个工厂系统在每个小时内最多能加工多少台电脑? 解题 ...
- POJ 3436 ACM Computer Factory 最大流,拆点 难度:1
题目 http://poj.org/problem?id=3436 题意 有一条生产线,生产的产品共有p个(p<=10)零件,生产线上共有n台(n<=50)机器,每台机器可以每小时加工Qi ...
- POJ 3436 ACM Computer Factory (网络流,最大流)
POJ 3436 ACM Computer Factory (网络流,最大流) Description As you know, all the computers used for ACM cont ...
- POJ - 3436 ACM Computer Factory 网络流
POJ-3436:http://poj.org/problem?id=3436 题意 组配计算机,每个机器的能力为x,只能处理一定条件的计算机,能输出特定的计算机配置.进去的要求有1,进来的计算机这个 ...
- POJ - 3436 ACM Computer Factory(最大流)
https://vjudge.net/problem/POJ-3436 题目描述: 正如你所知道的,ACM 竞赛中所有竞赛队伍使用的计算机必须是相同的,以保证参赛者在公平的环境下竞争.这就是所有这些 ...
- POJ 3436 ACM Computer Factory(最大流+路径输出)
http://poj.org/problem?id=3436 题意: 每台计算机包含P个部件,当所有这些部件都准备齐全后,计算机就组装完成了.计算机的生产过程通过N台不同的机器来完成,每台机器用它的性 ...
- POJ 3436 ACM Computer Factory (拆点+输出解)
[题意]每台计算机由P个零件组成,工厂里有n台机器,每台机器针对P个零件有不同的输入输出规格,现在给出每台机器每小时的产量,问如何建立流水线(连接各机器)使得每小时生产的计算机最多. 网络流的建图真的 ...
- POJ 3436 ACM Computer Factory
题意: 为了追求ACM比赛的公平性,所有用作ACM比赛的电脑性能是一样的,而ACM董事会专门有一条生产线来生产这样的电脑,随着比赛规模的越来越大,生产线的生产能力不能满足需要,所以说ACM董事会想 ...
- 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 ...
随机推荐
- hadoop配置远程客户端
独立出一台机器,作为客户端,可以连接远程集群,配置注意事项: 1.首先是hive,需要服务器启动一个服务 hive --service metastore 然后修改hive客户端 hive-site. ...
- thinkphp3.2设置session的过期时间
thinkPHP3.2中session的过期时间配置是不能使用的,我们需要修改一下它的配置文件thinkPHP>common>functions.php,找到这一行: if(isset($ ...
- 微信APP支付(Java后台生成签名具体步骤)
public class PayCommonUtil { //定义签名,微信根据参数字段的ASCII码值进行排序 加密签名,故使用SortMap进行参数排序 public static String ...
- 浅谈scrum站立会议
什么是每日站立会议? 站立会议是让团队成员每日面对面站立互相交流他们所承担任务的进度.它的一个附带好处是让领导或经理能了解到工作情况.但本质上是为了团队交流,不是报告会议! 为什么开展每日 ...
- BizTalk开发系列(六) BizTalk开发简述
现在很多大型企业信息化程度很高,运行中的系统可达到数十乃至上百个.而大部分系统由于建设的时间.开发团队和技术 往往不相同,系统之间的大部分都是独立运行的.随着信息化建设的深入各系统之间的交互需求越来越 ...
- 【iCore3 双核心板_FPGA】例程六:计数器实验——计数器使用
实验指导书及代码包下载: http://pan.baidu.com/s/1kUiAAt5 iCore3 购买链接: https://item.taobao.com/item.htm?id=524229 ...
- INSTRUCTION CYCLE
COMPUTER ORGANIZATION AND ARCHITECTURE DESIGNING FOR PERFORMANCE NINTH EDITION • Fetch: Read the nex ...
- 基于VirtualBox的多重载入
问题描述 这个问题要追溯到中秋之前,也就是写第一周博客的时候,当时我用的还是虚拟机上的ubuntu:当时我的ubuntu不是最新版,所以有提示升级,你懂的,我升了(因为时间有点久,我先去吃了个饭):等 ...
- [LeetCode]题解(python):125 Valid Palindrome
题目来源 https://leetcode.com/problems/valid-palindrome/ Given a string, determine if it is a palindrome ...
- LightOj 1197 - Help Hanzo(分段筛选法 求区间素数个数)
题目链接:http://lightoj.com/volume_showproblem.php?problem=1197 题意:给你两个数 a b,求区间 [a, b]内素数的个数, a and b ( ...