Cod sursa(job #714784)

Utilizator PetcuIoanPetcu Ioan Vlad PetcuIoan Data 16 martie 2012 09:52:24
Problema Taramul Nicaieri Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2 kb
#include<stdio.h>
#include<assert.h>

#include<vector>
#include<queue>
#include<algorithm>

using namespace std;

const int knmax = 227, ko9k = 900000000;
int verts, source, dest, flow, sol, vis[knmax], dad[knmax], cap[knmax][knmax], f[knmax][knmax];

void add_edges(int x, int enter, int exit){
    cap[source][x] = exit;
    cap[x + verts][dest] = enter;
}

void read(){
    assert(freopen("harta.in","r",stdin) != NULL);
    scanf("%d",&verts);

    source = 0;
    dest = 2 * verts + 1;

    int i, aux_x, aux_y;
    for(i = 1; i <= verts; ++i){
        scanf("%d%d",&aux_x,&aux_y);
        add_edges(i,aux_y,aux_x);
        sol += aux_y;
    }
}

void add_ALL_the_edges(){
    int i, j;
    for(i = 1; i <= verts; ++i)
        for(j = 1; j <= verts; ++j)
            if(i != j)
                cap[i][j + verts] = 1;
}

void init(){
    for(int i = 1; i <= dest; ++i)
        vis[i] = 0;
}

int bfs(){
    init();

    int now ,i;
    queue<int> q;
    q.push(source);
    while(!q.empty()){
        now = q.front();
        q.pop();

        for(i = 1; i <= dest; ++i)
            if(!vis[i] && cap[now][i] > f[now][i]){
                dad[i] = now;
                q.push(i);
                vis[i] = 1;
                if(i == dest)
                    return 1;
            }
    }
    return 0;
}

void solve(){
    add_ALL_the_edges();
    int c_flow, i;
    while(bfs()){
        c_flow = ko9k;

        for(i = dest; i != source; i = dad[i])
            c_flow = min(c_flow, cap[dad[i]][i] - f[dad[i]][i]);

        flow += c_flow;
        for(i = dest; i != source; i = dad[i]){
            f[dad[i]][i] += c_flow;
            f[i][dad[i]] -= c_flow;
        }
    }
}

void write(){
    assert(freopen("harta.out","w",stdout) != NULL);
    printf("%d\n",sol);
    int i, j;
    for(i = 1; i <= verts; ++i)
        for(j = 1; j <= verts; ++j)
            if(cap[i][j + verts] == f[i][j + verts] && f[i][j + verts] == 1)
                printf("%d %d\n",i,j);
}

int main(){
    read();
    solve();
    write();
    return 0;
}