Cod sursa(job #869036)

Utilizator a_h1926Heidelbacher Andrei a_h1926 Data 31 ianuarie 2013 21:23:03
Problema Cc Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.17 kb
#include <cstring>
#include <fstream>
#include <vector>
#include <queue>

using namespace std;

typedef vector<int>::iterator it;

const int MaxN = 205;
const int oo = 0x3f3f3f3f;

vector<int> G[MaxN];
int N, Cost[MaxN][MaxN], Distance[MaxN], Father[MaxN];
int Source, Sink, Capacity[MaxN][MaxN], Flow[MaxN][MaxN];
queue<int> Q;
bool InQ[MaxN];
int Solution;

void InitBF(int Start) {
    memset(Distance, oo, sizeof(Distance));
    memset(Father, -1, sizeof(Father));
    Distance[Start] = 0, Father[Start] = Start;
    Q.push(Start), InQ[Start] = true;
}

bool BellmanFord(int Start, int End) {
    for (InitBF(Start); !Q.empty(); Q.pop()) {
        int X = Q.front(); InQ[X] = false;
        if (X == End)
            continue;
        for (it Y = G[X].begin(); Y != G[X].end(); ++Y) {
            if (Capacity[X][*Y] > Flow[X][*Y] && Distance[X] + Cost[X][*Y] < Distance[*Y]) {
                Distance[*Y] = Distance[X] + Cost[X][*Y], Father[*Y] = X;
                if (!InQ[*Y])
                    Q.push(*Y), InQ[*Y] = true;
            }
        }
    }
    return Father[End] != -1;
}

int MaximumMatching() {
    int MaxMatch = 0, MatchCost = 0;
    while(BellmanFord(Source, Sink)) {
        for (int X = Sink; X != Source; X = Father[X])
            ++Flow[Father[X]][X], --Flow[X][Father[X]];
        MatchCost += Distance[Sink];
    }
    return MatchCost;
}

inline void AddEdge(int x, int y, int cost) {
    G[x].push_back(y), G[y].push_back(x);
    Cost[x][y] = cost, Cost[y][x] = -cost;
    Capacity[x][y] = 1, Capacity[y][x] = 0;
}

void Read() {
    ifstream in("cc.in");
    in >> N;
    for (int i = 1; i <= N; ++i) {
        for (int j = N + 1; j <= 2 * N; ++j) {
            int cost; in >> cost;
            AddEdge(i, j, cost);
        }
    }
    Source = 0, Sink = 2 * N + 1;
    for (int i = 1; i <= N; ++i)
        AddEdge(Source, i, 0);
    for (int i = N + 1; i <= 2 * N; ++i)
        AddEdge(i, Sink, 0);
    in.close();
}

void Print() {
    ofstream out("cc.out");
    out << Solution << "\n";
    out.close();
}

int main() {
    Read();
    Solution = MaximumMatching();
    Print();
    return 0;
}