Cod sursa(job #1147850)

Utilizator andreiiiiPopa Andrei andreiiii Data 20 martie 2014 10:49:09
Problema Cc Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.89 kb
#include <algorithm>
#include <bitset>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>

using namespace std;

const int N=205, S=0, D=204, INF=0x3f3f3f3f;

vector <int> G[N];
int C[N][N], F[N][N], Cost[N][N], Tr[N], dist[N];
int n, flow, flow_cost;
bitset <N> v;

bool bellman_ford()
{
    int x, fmin, i;
    queue <int> Q;
    memset(dist, INF, sizeof(dist));
    dist[S]=0;
    v.reset();
    for(Q.push(S);!Q.empty();Q.pop())
    {
        x=Q.front();
        v[x]=0;
        for(vector<int>::iterator it=G[x].begin();it!=G[x].end();it++)
        {
            if(C[x][*it]==F[x][*it]) continue;
            if(dist[x]+Cost[x][*it]<dist[*it])
            {
                dist[*it]=dist[x]+Cost[x][*it];
                Tr[*it]=x;
                if(!v[*it])
                {
                    v[*it]=1;
                    Q.push(*it);
                }
            }
        }
    }
    fmin=INF;
    for(i=D;i!=S;i=Tr[i])
    {
        fmin=min(fmin, C[Tr[i]][i]-F[Tr[i]][i]);
    }
    for(i=D;i!=S;i=Tr[i])
    {
        F[Tr[i]][i]+=fmin;
        F[i][Tr[i]]-=fmin;
    }
    flow+=fmin;
    flow_cost+=fmin*dist[D];
    if(flow==n) return false;
    return true;
}

int main()
{
    freopen("cc.in", "r", stdin);
    freopen("cc.out", "w", stdout);
    int i, j;
    scanf("%d", &n);
    for(i=1;i<=n;i++)
    {
        for(j=n+1;j<=2*n;j++)
        {
            scanf("%d", &Cost[i][j]);
            Cost[j][i]=-Cost[i][j];
            G[i].push_back(j);
            G[j].push_back(i);
            C[i][j]=1;
        }
    }
    for(i=1;i<=n;i++)
    {
        G[S].push_back(i);
        G[i].push_back(S);
        C[S][i]=1;
    }
    for(i=n+1;i<=2*n;i++)
    {
        G[i].push_back(D);
        G[D].push_back(i);
        C[i][D]=1;
    }
    while(bellman_ford());
    printf("%d\n", flow_cost);
}