Cod sursa(job #2251845)

Utilizator circeanubogdanCirceanu Bogdan circeanubogdan Data 2 octombrie 2018 00:58:26
Problema Cc Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.7 kb
#include <fstream>
#include <vector>
#include <bitset>
#include <queue>
#define DIM 210
#define INF 1e9

using namespace std;

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

int N, solution;
int dist[DIM], father[DIM];
int cost[DIM][DIM], capacity[DIM][DIM], flow[DIM][DIM];

vector<int> graph[DIM];

bitset<DIM> visited;

queue<int> q;

bool bf(){
    visited.reset();
    while(!q.empty())
        q.pop();
    for(int cnt = 0; cnt <= 2 * N + 1; ++ cnt){
        dist[cnt] = INF;
        father[cnt] = -1;
    }
    dist[0] = 0;
    q.push(0);
    visited[0] = true;
    
    while(!q.empty()){
        int currentNode = q.front();
        q.pop();
        visited[currentNode] = false;
        for(auto nextNode : graph[currentNode]){
            if(capacity[currentNode][nextNode] - flow[currentNode][nextNode] > 0 && dist[nextNode] > dist[currentNode] + cost[currentNode][nextNode]){
                dist[nextNode] = dist[currentNode] + cost[currentNode][nextNode];
                father[nextNode] = currentNode;
                if(!visited[nextNode]){
                    visited[nextNode] = true;
                    q.push(nextNode);
                }
            }
        }
    }
    return father[2 * N + 1] > -1;
}

int main(int argc, const char * argv[]) {
    in>>N;
    for(int concCnt = 1; concCnt <= N; ++ concCnt){
        for(int calcCnt = N + 1; calcCnt <= 2 * N; ++ calcCnt){
            in>>cost[concCnt][calcCnt];
            cost[calcCnt][concCnt] = -cost[concCnt][calcCnt];
            capacity[concCnt][calcCnt] = 1;
        }
    }
    
    for(int concCnt = 1; concCnt <= N; ++ concCnt){
        graph[0].push_back(concCnt);
        graph[concCnt].push_back(0);
        for(int calcCnt = N + 1; calcCnt <= 2 * N; ++ calcCnt){
            graph[concCnt].push_back(calcCnt);
            graph[calcCnt].push_back(concCnt);
        }
        capacity[0][concCnt] = 1;
    }
    for(int calcCnt = N + 1; calcCnt <= 2 * N; ++ calcCnt){
        graph[calcCnt].push_back(2 * N + 1);
        graph[2 * N + 1].push_back(calcCnt);
        capacity[calcCnt][2 * N + 1] = 1;
    }
    
    while(bf()){
        int currentNode = 2 * N + 1;
        int minFlow = INF;
        while(currentNode){
            minFlow = min(minFlow, capacity[father[currentNode]][currentNode] - flow[father[currentNode]][currentNode]);
            currentNode = father[currentNode];
        }
        
        currentNode = 2 * N + 1;
        solution += dist[currentNode] * minFlow;
        while (currentNode) {
            
            flow[father[currentNode]][currentNode] += minFlow;
            flow[currentNode][father[currentNode]] -= minFlow;
            currentNode = father[currentNode];
        }
        
    }
    
    out<<solution;
    return 0;
}