ACM Computer Factory POJ - 3436 (最大流 && 输出路径)

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);
        }
    }

  }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值