Cod sursa(job #318741)

Utilizator Magnuscont cu nume gresit sau fals Magnus Data 29 mai 2009 09:59:04
Problema Cc Scor 40
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.51 kb
#include <cstdio>     
#include <cstring>     
#include <vector>     
#include <queue>     
using namespace std;     
     
#define inf 0x3f3f3f3f     
     
const int maxn = 2 * 52;
     
int n;     
int f[maxn][maxn], c[maxn][maxn], cost[maxn][maxn];     
vector<int> g[maxn];     
     
int inq[maxn], d[maxn], p[maxn];     
     
int S, D;     
     
void read()     
{     
    scanf("%d", &n);     
    S = 0; D = 2 * n + 1;     
    for (int i = 1; i <= n; ++i)     
    for (int j = 1; j <= n; ++j)     
    {     
        int x; scanf("%d", &x);      
        g[i].push_back(j + n);     
        g[j + n].push_back(i);     
        cost[i][j + n] = x;     
        cost[j + n][i] = -x;     
        c[i][j + n] = 1;     
    }     
    for (int i = 1; i <= n; ++i)     
    {     
    g[0].push_back(i); g[i].push_back(0);     
    c[0][i] = 1;     
     
    g[i + n].push_back(D); g[D].push_back(i + n);     
    c[i + n][D] = 1;     
    }     
}     
     
int ok = 1;     
     
int bf()     
{     
    memset(d, 0x3f, sizeof(d));     
    memset(inq, 0, sizeof(inq));     
    queue<int> Q;     
    Q.push(S); d[S] = 0;     
     
    while (!Q.empty())     
    {     
    int akt = Q.front(); Q.pop();     
    for (int i = 0; i < g[akt].size(); ++i)     
    {     
        int next = g[akt][i];     
        if (c[akt][next] - f[akt][next] == 0) continue;     
     
        if (d[next] > d[akt] + cost[akt][next])     
        {     
        d[next] = d[akt] + cost[akt][next];     
        p[next] = akt;     
        if (!inq[next])     
        {     
            Q.push(next);     
            inq[next] = 1;     
        }     
        }     
    }     
    inq[akt] = 0;     
    }     
     
    if (d[D] != inf)     
    {     
    ok = 1;     
    int minn = inf;     
    for (int i = D; i != 0; i = p[i])     
        minn = min(minn, c[p[i]][i] - f[p[i]][i]);     
    for (int i = D; i != 0; i = p[i])     
    {     
        f[p[i]][i] += minn;      
        f[i][p[i]] -= minn;     
    }     
     
    return minn * d[D];     
    }     
     
    return 0;     
}     
     
void flux()     
{     
    int res = 0;     
    while (ok)      
    {     
    ok = 0;     
    res += bf();     
    }      
    printf("%d\n", res);     
}     
     
int main()     
{     
    freopen("cc.in","r",stdin);     
    freopen("cc.out","w",stdout);     
     
    read();     
    flux();     
     
    return 0;     
}