1. 程式人生 > >POJ-3436 ACM Computer Factory(網絡流EK)

POJ-3436 ACM Computer Factory(網絡流EK)

In 超過 scanf TE ctu ever gif upgrade move

As you know, all the computers used for ACM contests must be identical, so the participants compete on equal terms. That is why all these computers are historically produced at the same factory.

Every ACM computer consists of P parts. When all these parts are present, the computer is ready and can be shipped to one of the numerous ACM contests.

Computer manufacturing is fully automated by using N various machines. Each machine removes some parts from a half-finished computer and adds some new parts (removing of parts is sometimes necessary as the parts cannot be added to a computer in arbitrary order). Each machine is described by its performance (measured in computers per hour), input and output specification.

Input specification describes which parts must be present in a half-finished computer for the machine to be able to operate on it. The specification is a set of P numbers 0, 1 or 2 (one number for each part), where 0 means that corresponding part must not be present, 1 — the part is required, 2 — presence of the part doesn’t matter.

Output specification describes the result of the operation, and is a set of P numbers 0 or 1, where 0 means that the part is absent, 1 — the part is present.

The machines are connected by very fast production lines so that delivery time is negligibly small compared to production time.

After many years of operation the overall performance of the ACM Computer Factory became insufficient for satisfying the growing contest needs. That is why ACM directorate decided to upgrade the factory.

As different machines were installed in different time periods, they were often not optimally connected to the existing factory machines. It was noted that the easiest way to upgrade the factory is to rearrange production lines. ACM directorate decided to entrust you with solving this problem.

Input
Input file contains integers P N, then N descriptions of the machines. The description of ith machine is represented as by 2 P + 1 integers Qi Si,1 Si,2…Si,P Di,1 Di,2…Di,P, where Qi specifies performance, Si,j — input specification for part j, Di,k — output specification for part k.

Constraints

1 ≤ P ≤ 10, 1 ≤ N ≤ 50, 1 ≤ Qi ≤ 10000

Output
Output the maximum possible overall performance, then M — number of connections that must be made, then M descriptions of the connections. Each connection between machines A and B must be described by three positive numbers A B W, where W is the number of computers delivered from A to B per hour.

If several solutions exist, output any of them.

Sample Input
3 4
15 0 0 0 0 1 0
10 0 0 0 0 1 1
30 0 1 2 1 1 1
3 0 2 1 1 1 1
3 5
5 0 0 0 0 1 0
100 0 1 0 1 0 1
3 0 1 0 1 1 0
1 1 0 1 1 1 0
300 1 1 2 1 1 1
2 2
100 0 0 1 0
200 0 1 1 1
Sample Output
25 2
1 3 15
2 3 10
4 5
1 3 3
3 5 3
1 2 1
2 4 1
4 5 1
0 0

—————————————————–分割線——————————————————–

題意,有N個機器,每個機器對P個部分進行加工,但是每個機器對加工的對象都有要求,題中input specification 代表機器加工的對象必須滿足的條件,其中為0的部分絕對不能存在,為1的部分必須存在,為2的部位存在與不存在都可以。Output specification 代表機器加工完成後的對象, 其中為0的部分代表加工後不存在,為1的部分代表加工後存在。用這些機器將全為0的零件加工成全為1的電腦。給出每個機器的加工速度,加工對象和加工後對象,求最快的加工速度。
解釋案例:
3 4
15 0 0 0 0 1 0
10 0 0 0 0 1 1
30 0 1 2 1 1 1
3 0 2 1 1 1 1
有四個機器,每個機器對三個地方加工。
一開始的板子是空的,所以只能用0 0 0 開始的機器來加工,所以一開始只有1號和2號機子可以用,用1號機子後變成0 1 0 然後拿去三號機子,變成1 1 1,這一條路加工速度為15。用2號機子加工變成0 1 1,然後拿去三號機子加工,這條路加工為10,所以總的速度是25。
思路:對於每個點先要把點分割開,把點分開成兩部分的意義在於,不能讓最大流量超過本身的生產量。這是因為每個點我都需要一進一出,而我自己又有自己最大的生產量,所以我要保證在網絡流圖上跑的時候不僅不會超過前一個點帶來的流量,也不會超過自己本身所可以承受的流量。如圖:
假設c能承受的流量只有15
技術分享圖片
如果按這個圖跑,那麽我會超出自身可以承受的流量,超出15,使最大流變成30,這顯然是不可以的
技術分享圖片
那麽我這時候就需要對c點進行拆點,是一條從自身到自身的路的權值是自身的生產量,這樣我就保證了我不會超出自身最大可以承受的流量。
同理,在這題中就需要對每個點來進行拆點,然後一個點用來接收流量,一個點用來發送流量,在這兩個點之間用本身可以承受的最大流量來將這兩個點連接起來,在這題中也就是本身的生產速度。最後跑一邊最大流,然後對每條邊判斷,如果一開始的邊比跑完以後的邊的權值大,那麽就說明有流量經過。

技術分享圖片
#include<map>
#include<ctime>
#include<cmath>
#include<stack>
#include<queue>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>

typedef unsigned long long int ull;
typedef long long int ll;
const double pi = 4.0*atan(1.0);
const int inf = 0x3f3f3f3f;
const int maxn = 105;
const int maxm = 100005;
using namespace std;

int n, m;
int maps[maxn][maxn];
int flow[maxn];
int pre[maxn];
int tmp[maxn][maxn];
int inp[maxn][maxn];
int oup[maxn][maxn];
int res[maxm][3];
queue<int> q;

void init() {
    memset(inp, 0, sizeof(inp));
    memset(oup, 0, sizeof(oup));
    memset(tmp, 0, sizeof(tmp));
    memset(res, 0, sizeof(res));
    memset(maps, 0, sizeof(maps));
    memset(flow, 0, sizeof(flow));
}

void getmap() {
    int src = 0;
    int des = 2 * m + 1;
    int val;
    for(int i=1; i<=m; i++) {
        scanf("%d", &val);
        maps[i][i+m] = val;
        bool flag = true;
        for(int j=1; j<=n; j++) {
            scanf("%d", &inp[i][j]);
            if(inp[i][j] == 1)    flag = false;
        }
        if(flag)
            maps[src][i] = inf;
        flag = true;
        for(int j=1; j<=n; j++) {
            scanf("%d", &oup[i][j]);
            if(oup[i][j] == 0)    flag = false;
        }
        if(flag)
            maps[i + m][des] = inf;
    }
    for(int i=1; i<=m; i++) {
        for(int j=1; j<=m; j++) {
            if(i == j)    continue;
            int flag = true;
            for(int k=1; k<=n; k++) {
                if(oup[i][k] == 1 && inp[j][k] == 0)    flag = false;
                if(oup[i][k] == 0 && inp[j][k] == 1)    flag = false;
            }
            if(flag)
                maps[i+m][j] = inf;
        }
    }
}

int bfs(int src, int des) {
    while(!q.empty())    q.pop();
    memset(pre, -1, sizeof(pre));
    q.push(src);
    pre[src] = 0;
    flow[src] = inf;
    while(!q.empty()) {
        int index = q.front();
        q.pop();
        if(index == des)    break;
        for(int i=src; i<=des; i++) {
            if(i != src && maps[index][i] && pre[i] == -1) {
                pre[i] = index;
                flow[i] = min(flow[index], maps[index][i]);
                q.push(i);
            }
        }
    }
    if(pre[des] == -1)    return -1;
    else    return flow[des];
}

int EK(int src, int des) {
    int ans = 0;
    int val;
    while(1) {
        val = bfs(src, des);
        if(val == -1)    break;
        int last = des;
        while(last != src) {
            maps[pre[last]][last] -= val;
            maps[last][pre[last]] += val;
            last = pre[last];
        }
        ans += val;
    }
    return ans;
}

int solve() {
    int ans = 0;
    for(int i=1; i<=m; i++) {
        for(int j=1; j<=m; j++) {
            if(tmp[i + m][j] - maps[i + m][j] > 0) {
                res[ans][0] = i;
                res[ans][1] = j;
                res[ans][2] = tmp[i + m][j] - maps[i + m][j];
                ans++;
            }
        }
    }
    return ans;
}

int main() {
    while(~scanf("%d%d", &n, &m)) {
        init();
        getmap();
        int src = 0;
        int des = 2 * m + 1;
        /*
        for(int i=src; i<=des; i++) {
            for(int j=src; j<=des; j++) {
                printf("%d%c", maps[i][j], j==des ? ‘\n‘ : ‘\t‘);
            }
        }
        */
        memcpy(tmp, maps, sizeof(maps));
        int ans = EK(src, des);
        int tol = solve();
        printf("%d %d\n", ans, tol);
        for(int i=0; i<tol; i++) {
            printf("%d %d %d\n", res[i][0], res[i][1], res[i][2]);
        }
    }
    return 0;
}
View Code

POJ-3436 ACM Computer Factory(網絡流EK)