Cod sursa(job #555318)

Utilizator feelshiftFeelshift feelshift Data 15 martie 2011 13:43:31
Problema Cc Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.69 kb
// http://infoarena.ro/problema/cc
#include <fstream>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;

#define to first
#define cost second

const int maxSize = 202;
const int oo = 0x3f3f3f3f;
const int source = 0;
const int sink = 201;

ifstream in("cc.in");
ofstream out("cc.out");

int nodes,minCost;
bool visit[maxSize];
int father[maxSize];
int dist[maxSize];
int capacity[maxSize][maxSize];
int currentFlow[maxSize][maxSize];
vector< pair<int,int> > graph[maxSize];

bool bellmanFord();

int main() {
    in >> nodes;

    int currentCost;
    for(int i=1;i<=nodes;i++)
        for(int k=1;k<=nodes;k++) {
            in >> currentCost;
            int tmp = k + nodes;

            graph[i].push_back(make_pair(tmp,currentCost));
            graph[tmp].push_back(make_pair(i,-currentCost));

            capacity[i][tmp] = 1;
        }

    for(int i=1;i<=nodes;i++) {
        graph[source].push_back(make_pair(i,0));
        graph[i].push_back(make_pair(source,0));
        capacity[source][i] = 1;
    }

    for(int i=nodes+1;i<=nodes+nodes;i++) {
        graph[i].push_back(make_pair(sink,0));
        graph[sink].push_back(make_pair(i,0));
        capacity[i][sink] = 1;
    }

    while(bellmanFord()) {
        int minFlow = oo;
        for(int node=sink;node!=source;node=father[node])
            minFlow = min(minFlow,capacity[father[node]][node] - currentFlow[father[node]][node]);

        for(int node=sink;node!=source;node=father[node]) {
            currentFlow[father[node]][node] += minFlow;
            currentFlow[node][father[node]] -= minFlow;
        }

        minCost += minFlow * dist[sink];
    }

    out << minCost << "\n";

    in.close();
    out.close();

    return (0);
}

bool bellmanFord() {
    memset(visit,false,sizeof(visit));
    visit[source] = true;

    memset(dist,oo,sizeof(dist));
    dist[source] = 0;

    int node;
    vector< pair<int,int> >::iterator it,end;

    queue<int> myQueue;
    myQueue.push(source);

    while(!myQueue.empty()) {
        node = myQueue.front();
        myQueue.pop();

        if(node == sink)
            continue;

        end = graph[node].end();
        for(it=graph[node].begin();it!=end;++it)
            if(capacity[node][it->to] > currentFlow[node][it->to] && dist[it->to] > dist[node] + it->cost) {
                dist[it->to] = dist[node] + it->cost;
                father[it->to] = node;

                if(!visit[it->to]) {
                    visit[it->to] = true;
                    myQueue.push(it->to);
                }
            }

        visit[node] = false;
    }

    return (dist[sink] != oo);
}