POJ 3436 ACM Computer Factory (最大流 + 輸出路徑)

來源:互聯網
上載者:User

標籤:網路流   圖論   

POJ 3436 ACM Computer Factory 連結:http://poj.org/problem?id=3436
題意:每台電腦有P部分,可以通過不同的機器來進行加工。有N台機器,每台機器用2 P +1 個整數來描述:Qi  Si,1  Si,2 ...  Si,p  Di,1  Di,2. ..  Di,p,其中Qi 指定了機器的效能,表示每小時加工的電腦數量。Si,j 為第j 部分的輸入規格,0表示該部分不能被加工過,1表示該部分必須被加工過,2表示都可以。Di,k 為第k 部分的輸出規格。0表示經過該機器不加工,1表示該機器加工該部分。1≤P≤10,1≤N≤50,1≤Qi≤10000。
思路:建立一個源點,只要每台機器的s部分沒有1,即從源點向其連邊,流量為該機器的效率。建立一個匯點,只要每台機器的D部分全部為1,則向匯點連邊,流量為機器的效率。如果某個機器的輸出部分符合某個機器的輸入部分,則兩者連邊,流量為min(Qi, Qj)。觀察發現如果 j 機器的輸入部分為2,這 i 機器輸出部分隨意,否則j的輸出部分必須與輸入部分相同。
PS:這道題也可以拆點來做,將每個機器的輸入部分和輸出部分分開,並連邊,流量為機器效率,然後不同機器之間匹配的話,流量就為INF。同時源點和匯點與機器連邊時,流量也為INF。
代碼:
/*ID: [email protected]PROG:LANG: C++*/#include<map>#include<set>#include<queue>#include<stack>#include<cmath>#include<cstdio>#include<vector>#include<string>#include<fstream>#include<cstring>#include<ctype.h>#include<iostream>#include<algorithm>using namespace std;#define LINF (1LL<<60)#define INF (1<<30)#define PI acos(-1.0)#define mem(a, b) memset(a, b, sizeof(a))#define rep(i, a, n) for (int i = a; i < n; i++)#define per(i, a, n) for (int i = n - 1; i >= a; i--)#define eps 1e-6#define debug puts("===============")#define pb push_back//#define mp make_pair#define all(x) (x).begin(),(x).end()#define fi first#define se second#define SZ(x) ((int)(x).size())#define POSIN(x,y) (0 <= (x) && (x) < n && 0 <= (y) && (y) < m)typedef long long ll;typedef unsigned long long ULL;const int maxn = 60;const int maxm = 20000;int st, ed, n;int P, N;int S[maxn][10], D[maxn][10], Q[maxn];struct node {    int v;    // vertex    int cap;    // capacity    int flow;   // current flow in this arc    int nxt;} e[maxm * 2];int g[maxn], cnt;void add(int u, int v, int c) {    e[++cnt].v = v;    e[cnt].cap = c;    e[cnt].flow = 0;    e[cnt].nxt = g[u];    g[u] = cnt;    e[++cnt].v = u;    e[cnt].cap = 0;    e[cnt].flow = 0;    e[cnt].nxt = g[v];    g[v] = cnt;}bool check(int x, int y) {    for (int i = 0; i < P; i++) if (S[y][i] != 2) {        if (S[y][i] != D[x][i]) return false;    }    return true;}void init() {    mem(g, 0);    cnt = 1;    scanf("%d%d", &P, &N);    st = 0, ed = N + 1;    int ok;    for (int i = 1; i <= N; i++) {        scanf("%d", Q + i);        ok = 0;        for (int j = 0; j < P; j++) {            scanf("%d", S[i] + j);            if (S[i][j] == 1) ok++;        }        if (!ok) add(st, i, Q[i]);        ok = 0;        for (int j = 0; j < P; j++) {            scanf("%d", D[i] + j);            if (D[i][j] == 1) ok++;        }        if (ok == P) add(i, ed, Q[i]);    }    for (int i = 1; i <= N; i++) {        for (int j = i + 1; j <= N; j++) {            if (check(i, j)) add(i, j, min(Q[i], Q[j]));            if (check(j, i)) add(j, i, min(Q[i], Q[j]));        }    }    n = N + 3;}int dist[maxn], numbs[maxn], q[maxn];void rev_bfs() {    int font = 0, rear = 1;    for (int i = 0; i <= n; i++) { //n為總點數        dist[i] = maxn;        numbs[i] = 0;    }    q[font] = ed;    dist[ed] = 0;    numbs[0] = 1;    while(font != rear) {        int u = q[font++];        for (int i = g[u]; i; i = e[i].nxt) {            if (e[i ^ 1].cap == 0 || dist[e[i].v] < maxn) continue;            dist[e[i].v] = dist[u] + 1;            ++numbs[dist[e[i].v]];            q[rear++] = e[i].v;        }    }}int maxflow() {    rev_bfs();    int u, totalflow = 0;    int curg[maxn], revpath[maxn];    for(int i = 0; i <= n; ++i) curg[i] = g[i];    u = st;    while(dist[st] < n) {        if(u == ed) {   // find an augmenting path            int augflow = INF;            for(int i = st; i != ed; i = e[curg[i]].v)                augflow = min(augflow, e[curg[i]].cap);            for(int i = st; i != ed; i = e[curg[i]].v) {                e[curg[i]].cap -= augflow;                e[curg[i] ^ 1].cap += augflow;                e[curg[i]].flow += augflow;                e[curg[i] ^ 1].flow -= augflow;            }            totalflow += augflow;            u = st;        }        int i;        for(i = curg[u]; i; i = e[i].nxt)            if(e[i].cap > 0 && dist[u] == dist[e[i].v] + 1) break;        if(i) {   // find an admissible arc, then Advance            curg[u] = i;            revpath[e[i].v] = i ^ 1;            u = e[i].v;        } else {    // no admissible arc, then relabel this vertex            if(0 == (--numbs[dist[u]])) break;    // GAP cut, Important!            curg[u] = g[u];            int mindist = n;            for(int j = g[u]; j; j = e[j].nxt)                if(e[j].cap > 0) mindist = min(mindist, dist[e[j].v]);            dist[u] = mindist + 1;            ++numbs[dist[u]];            if(u != st)                u = e[revpath[u]].v;    // Backtrack        }    }    return totalflow;}int out[maxm][3], tot = 0;void get_out() {    for (int u = 1; u < ed; u++) {        for (int i = g[u]; i; i = e[i].nxt) {            if (e[i].v != ed && e[i].flow > 0) {                out[tot][0] = u;                out[tot][1] = e[i].v;                out[tot++][2] = e[i].flow;            }        }    }}int main () {    init();    printf("%d ", maxflow());    get_out();    printf("%d\n", tot);    for (int i = 0; i < tot; i++) {        printf("%d %d %d\n", out[i][0], out[i][1], out[i][2]);    }    return 0;}


POJ 3436 ACM Computer Factory (最大流 + 輸出路徑)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.