Cod sursa(job #2071009)

Utilizator EuAlexOtaku Hikikomori EuAlex Data 20 noiembrie 2017 09:01:46
Problema Taramul Nicaieri Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.64 kb
#include <cstdio>
#include <vector>
#include <algorithm>
#include <queue>

using namespace std;

const int inf = 2000000000;

int n, src, dr;
int cap[204][204], drum[204][204], flow[204][204];

queue <int> q;
int dist[204];
int bfs() {
    fill(dist, dist + n, -1);
    q.push(src);
    dist[src] = 0;

    while(!q.empty()) {
        int from = q.front();
        for(int k = 0; k < n; ++ k) {
            if(drum[from][k] == 1) {
                if(dist[k] == -1 && flow[from][k] < cap[from][k]) {
                    dist[k] = dist[from] + 1;
                    q.push(k);
                }
            }
        }
        q.pop();
    }

    return (dist[dr] > -1);
}

int minim(int a, int b) {
    if(a > b)
        return b;
    return a;
}

int rem[204];
int dfs(int from, int minflow) {
    if(from == dr) {
        return minflow;
    } else {
        for(int k = rem[from]; k < n; ++ k) {
            if(drum[from][k] == 1) {
                if(dist[from] == dist[k] - 1) {
                    int deltaflow = dfs(k, minim(minflow, cap[from][k] - flow[from][k]));

                    if(deltaflow > 0) {
                        flow[from][k] += deltaflow;
                        flow[k][from] -= deltaflow;
                        rem[from] = k + 1;
                        return deltaflow;
                    }
                }
            }
        }
        return 0;
    }
}

void maxflow() {
    int raspuns = 0, deltaflow;
    while(bfs() == 1) {
        fill(rem, rem + n, 0);
        do {
            deltaflow = dfs(src, inf);
            raspuns += deltaflow;
        }while(deltaflow > 0);
    }
}

int main() {
    freopen("harta.in", "r", stdin);
    freopen("harta.out", "w", stdout);

    scanf("%d", &n);
    n *= 2;
    src = n ++;
    dr = n ++;

    int sum = 0;
    for(int i = 0; i < n - 2; i += 2) {
        int out, in;
        scanf("%d%d", &out, &in);

        drum[i][dr] = 1;
        drum[dr][i] = 1;
        cap[i][dr] = in;
        drum[src][i + 1] = 1;
        drum[i + 1][src] = 1;
        cap[src][i + 1] = out;

        sum += in;
    }

    for(int i = 0; i < n - 2; i += 2) {
        for(int j = 0; j < n - 2; j += 2) {
            if(j != i) {
                drum[i + 1][j] = 1;
                drum[j][i] = 1;
                cap[i + 1][j] = 1;
            }
        }
    }

    maxflow();
    printf("%d\n", sum);

    for(int i = 1; i < n - 2; i += 2) {
        for(int j = 0; j < n; ++ j) {
            if(flow[i][j] > 0) {
                printf("%d %d\n", i / 2 + 1, j / 2 + 1);
            }
        }
    }

    return 0;
}