POJ-3436-ACM Computer Factory (maximum flow output path)

link:

https://vjudge.net/problem/POJ-3436#author=0

Meaning of the questions:

In order to pursue the fairness of the ACM contest, all used ACM game PC performance is the same, and the ACM board of directors has a special production line to produce such a computer, as more large-scale competition, the production capacity of the production line can not meet the needs of , so that the ACM board of directors want to re-build a production line. Production line is fully automated, so you need a machine to make up the production line, given the number of kinds of machines, standard ACM computer how many parts, each machine will be what kind of ACM computer semi-processed into what kind of computer semi-finished products (for input PC semi-finished products, every part of a 0,1,2 three states: 0 stands for, I can not be part of this process, 1, this part must have me to deal with, 2, there is no part of this I can handle for. 0,1 semifinished computer output have two states: 0 represents the processing after the computer is not in this part of the semi-finished product, 1, processed with a computer that semifinished part), it can be processed per hour per machine Q semi-finished products ( Qi in the input data). Seeking assembled to a maximum operating efficiency of the production line (how much per hour up to generate the finished product, the finished product is defined is part of the state of all "1") input line of the first two numbers: P represents a P-parts, a N represents an N machines. Next N rows, each row has a digital Qi, i representative of the number of parts of the semi-finished part processed per hour. Then 2 * P digits, the first number is the P of semi-finished condition to be met before processing, after the number represents the number P of semi-finished products after processing.

Ideas:

Maximum flow, does not require parts of the machine from the source s is connected to its one edge, the outputs of all the parts of a machine connected to the sink edge, the weights are infinite. Each machine simultaneously as two points, input connected weight value is output to q, the condition of the two machines connected one side, a weight of infinity.
construction FIG completed, the maximum flow can run.

Code:

#include <iostream>
#include <cstdio>
#include <vector>
#include <memory.h>
#include <queue>
#include <set>
#include <map>
#include <algorithm>
#include <math.h>
#include <stack>
using namespace std;
typedef long long LL;
const int MAXN = 50+10;
const int INF = 1e9;

struct Edge
{
    int from, to, cap;
    Edge(int f, int t, int c):from(f), to(t), cap(c){};
};
int Part[MAXN][2][15];//in:0, out:1
int Cap[MAXN];
vector<Edge> edges;
vector<int> G[MAXN];
int Dgree[MAXN], Vis[MAXN];
int Flowf[3000], Flowt[3000], Flowc[3000];
int Map[MAXN*3][MAXN*3];

int p, n;
int s, t;

bool Sto(int node)
{
    for (int i = 1;i <= p;i++)
        if (Part[node][0][i] == 1)
            return false;
    return true;
}

bool Tot(int node)
{
    for (int i = 1;i <= p;i++)
        if (Part[node][1][i] == 0)
            return false;
    return true;
}

bool IsLink(int a, int b)
{
    for (int i = 1;i <= p;i++)
        if (Part[a][1][i]+Part[b][0][i] == 1)
            return false;
    return true;//12, 11, 00, 02
}

void AddEdge(int from, int to, int cap)
{
    edges.push_back(Edge(from, to, cap));
    edges.push_back(Edge(to, from, 0));
    G[from].push_back(edges.size()-2);
    G[to].push_back(edges.size()-1);
}

bool Bfs()
{
    //构造分层网络
    memset(Dgree, -1, sizeof(Dgree));
    queue<int> que;
    que.push(s);
    Dgree[s] = 0;
    while (!que.empty())
    {
        int u = que.front();
        que.pop();
        for (int i = 0;i < G[u].size();i++)
        {
            Edge &e = edges[G[u][i]];
            if (e.cap > 0 && Dgree[e.to] == -1)
            {
                que.push(e.to);
                Dgree[e.to] = Dgree[u]+1;
            }
        }
    }
    return Dgree[t] != -1;
}

int Dfs(int u, int flow)
{
//    cout << u << endl;
    //flow 流量上线
    if (u == t)
        return flow;
    int res = 0;
    for (int i = 0; i < G[u].size() && flow; i++)
    {
        Edge &e = edges[G[u][i]];
        if (e.cap > 0 && Dgree[e.to] == Dgree[u] + 1)
        {
            int tmp = Dfs(e.to, min(flow, e.cap));
            flow -= tmp;
            e.cap -= tmp;
            res += tmp;
            edges[G[u][i] ^ 1].cap += tmp;
        }
    }
    if (res == 0)
        Dgree[u] = -1;
    return res;
}

int Dinic()
{
    int res = 0;
    while (Bfs())
        res += Dfs(0, INF);
    return res;
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    while (cin >> p >> n)
    {
        memset(Map, 0, sizeof(Map));
        edges.clear();
        for (int i = 0;i <= 2*n+1;i++)
            G[i].clear();
        s = 0, t = 2*n+1;
        for (int i = 1;i <= n;i++)
        {
            cin >> Cap[i];
            for (int j = 1;j <= p;j++)
                cin >> Part[i][0][j];
            for (int j = 1;j <= p;j++)
                cin >> Part[i][1][j];
        }
        for (int i = 1;i <= n;i++)
        {
            if (Sto(i))
                AddEdge(0, i*2-1, INF);
            if (Tot(i))
                AddEdge(i*2, t, INF);
        }
        for (int i = 1;i <= n;i++)
        {
            for (int j = 1;j <= n;j++)
            {
                if (i == j)
                    continue;
                if (IsLink(i, j))
                    AddEdge(i*2, j*2-1, INF);
            }
        }
        for (int i = 1;i <= n;i++)
            AddEdge(i*2-1, i*2, Cap[i]);
        int res = Dinic();
        int cnt = 0;
        for (int i = 1;i <= n;i++)
        {
            for (int j = 0;j < G[i*2-1].size();j++)
            {
                Edge &e = edges[G[i*2-1][j]];
                int l = i, r = e.to/2;
                if (e.cap > 0 && e.to != 0 && l != r)
                {
                    Flowf[++cnt] = r;
                    Flowt[cnt] = l;
                    Flowc[cnt] = e.cap;
                }
            }
        }
        cout << res << ' ' << cnt << endl;
        for (int i = 1;i <= cnt;i++)
            cout << Flowf[i] << ' ' << Flowt[i] << ' ' << Flowc[i] << endl;
    }

    return 0;
}

Guess you like

Origin www.cnblogs.com/YDDDD/p/11297663.html