Cod sursa(job #1886699)

Utilizator antanaAntonia Boca antana Data 21 februarie 2017 08:37:22
Problema Cc Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.84 kb
#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>

#define MAXN 202
#define INF 0x3f3f3f3f

using namespace std;

int n, source, sink, maxflow, mincost, flow[MAXN][MAXN], capacity[MAXN][MAXN], cost[MAXN][MAXN], dad[MAXN], dist[MAXN], q[MAXN*MAXN];

inline bool bellmanford()
{
    int left, right, node, son, i, j;

    for(i=0; i<=2*n+1; ++i)
        dist[i] = INF;
    dist[source] = 0;
    left = right = 0;
    q[right++] = source;

    while(left < right) {
        node = q[left++];
        if(node == sink) continue;

        for(j=0; j<=2*n+1; ++j) {
            son = j;
            if(flow[node][son] < capacity[node][son] && dist[node] + cost[node][son] < dist[son]) {
                dist[son] = dist[node] + cost[node][son];
                dad[son] = node;
                q[right++] = son; } } }

    return dist[sink] != INF;
}

inline int pump()
{
    int node, minflow, a = 0;

    minflow = INF;
    for(node=sink; node!=source; node=dad[node])
        minflow = min(minflow, capacity[dad[node]][node] - flow[dad[node]][node]);
    if(minflow)
        for(node=sink; node!=source; node=dad[node])
            flow[dad[node]][node] += minflow, flow[node][dad[node]] -= minflow;

    a += minflow;
    mincost += a*dist[sink];

    return a;

}

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=1; j<=n; ++j) {
            scanf("%d", &cost[i][j+n]);
            capacity[i][j+n] = 1;
            cost[j+n][i] = -cost[i][j+n]; }

    source = 0;
    sink = 2*n+1;

    for(i=1; i<=n; ++i) {
        capacity[0][i] = 1;
        capacity[i+n][2*n+1] = 1; }


    while(bellmanford()) maxflow += pump();

    printf("%d", mincost);

    return 0;
}