ACM Computer Factory POJ - 3436 (最大流 && 输出路径)
题目链接
题目大意:有N台机器,每台机器有P部分,每部分都有各自的输入、输出规格,因此一台机器有P个输入规格,P个输出规格。每台机器有2*P+1种参数去描述:第一个参数Q:该机器的容量;接下来P个参数S:该机器各部分的输入规格;接下来P个参数D:该机器各部分的输出规格。
其中输入规格有三种情况:0,1,2
0:该部分不能存在
1:该部分必须保留
2:该部分可有可无
输出规格有2种情况:0,1
0:该部分不存在
1:该部分存在
问最多可以生产出多少个机器
然后输出生产出这些台机器的路径
思路就不说了,拆点建图挺简单的。主要是之前不会输出路径。
贴下代码
#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
const int INF = 0x3f3f3f3f;
const int maxn = 2000;
int in[55][30], out[55][30], data[50];
struct node {
int to, w, pre, next;
} Edge[maxn];
int Head[maxn], cur[maxn], level[maxn], cnt;
void add(int u, int v, int w) {
Edge[cnt] = (node) {v, w, w, Head[u]};
Head[u] = cnt++;
Edge[cnt] = (node) {u, 0, 0, Head[v]};
Head[v] = cnt++;
}
bool bfs(int s, int t) {
memset(level, -1, sizeof(level));
queue<int> q;
level[s] = 0;
q.push(s);
while(!q.empty()) {
int now = q.front();
q.pop();
for(int i = Head[now]; ~i; i = Edge[i].next) {
int to = Edge[i].to;
if(level[to] == -1 && Edge[i].w) {
q.push(to);
level[to] = level[now] + 1;
}
}
}
return level[t] != -1;
}
int dfs(int s, int t, int f) {
if(s == t) return f;
int flow = 0, d;
for(int &i = cur[s]; ~i; i = Edge[i].next) {
int to = Edge[i].to;
if(Edge[i].w && level[s] < level[to] && (d = dfs(to, t, min(f, Edge[i].w)))) {
f -= d;
Edge[i].w -= d;
Edge[i ^ 1].w += d;
flow += d;
if(!f) break;
}
}
if(!flow) level[s] = -1;
return flow;
}
int max_flow(int s, int e) {
int flow = 0;
while(bfs(s, e)) {
memcpy(cur, Head, sizeof(Head));
flow += dfs(s, e, INF);
}
return flow;
}
int main()
{
int p, n;
while(~scanf("%d %d", &p, &n)) {
for(int i = 1; i <= n; i++) {
scanf("%d", &data[i]);
for(int j = 0; j < p; j++) {
scanf("%d", &in[i][j]);
}
for(int j = 0; j < p; j++) {
scanf("%d", &out[i][j]);
}
}
cnt = 0;
memset(Head, -1, sizeof(Head));
for(int i = 1; i <= n; i++) {
int flag1 = true, flag2 = true;
for(int j = 0; j < p; j++) {
if(in[i][j] && in[i][j] != 2) flag1 = false;
if(!out[i][j]) flag2 = false;
}
if(flag1) add(0, i, INF);
if(flag2) add(i + n, 2 * n + 1, INF);
}
for(int i = 1; i <= n; i++) {
add(i, i + n, data[i]);
for(int j = 1; j <= n; j++) {
if(i == j) continue;
int k;
for(k = 0; k < p; k++) {
if((out[i][k] == 1 && in[j][k] == 0) || (out[i][k] == 0 && in[j][k] == 1))
break;
}
if(k == p) add(i + n, j, INF);
}
}
int v = max_flow(0, 2 * n + 1);
int ans = 0;
for(int i = n + 1; i <= 2 * n; i++) {
for(int j = Head[i]; ~j; j = Edge[j].next) {
if(Edge[j].to > 0 && Edge[j].to <= n && Edge[j].w < Edge[j].pre)
ans++;
}
}
printf("%d %d\n", v, ans);
for(int i = n + 1; i <= 2 * n; i++) {
for(int j = Head[i]; ~j; j = Edge[j].next) {
if(Edge[j].to > 0 && Edge[j].to <= n && Edge[j].w < Edge[j].pre)
printf("%d %d %d\n", i - n, Edge[j].to, Edge[j].pre - Edge[j].w);
}
}
}
}