Cod sursa(job #3191189)

Utilizator sad_carrotVisan Sebastian sad_carrot Data 8 ianuarie 2024 23:55:59
Problema Cc Scor 10
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.79 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <unordered_map>
#include <queue>
#include <deque>

using namespace std;

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

class Graph{
    int n, nr_noduri, s, t;
    int infinity = 1e8;
    vector<unordered_map<int, int>> adiac;
    vector<unordered_map<int, int>> costs;
public:
    Graph(){
        f >> n;
        nr_noduri = 2 * n;
        adiac.resize(nr_noduri);
        costs.resize(nr_noduri);
        int cost;
        for(int i = 0; i < n; i++){
            for(int j = 0; j < n; j++){
                f >> cost;
                adiac[i][j + n] = 1;
                adiac[j + n][i] = 0;
                costs[i][j + n] = cost;
                costs[j + n][i] = -cost;
            }
        }
    }
    void bad_matching(){
        vector<int> matching(n);
        for(int i = 0; i < n; i++) {
            matching[i] = i;
        }
        int aux;
        for(int i = 0; i < n; i++)
            for(int j = 0; j < n; j++){
                if(costs[i][matching[i] + n] + costs[j][matching[j] + n] > costs[i][matching[j] + n] + costs[j][matching[i] + n]){
                    aux = matching[j];
                    matching[j] = matching[i];
                    matching[i] = aux;
                }
            }
        for(int i = 0; i < n; i++){
            adiac[i][matching[i] + n] = 0;
            adiac[matching[i] + n][i] = 1;
        }
    }
    void cancel_negative_cycles(){
        vector<int> parent(nr_noduri);
        int nod = bellman_ford(parent);
        while(nod != -1) {
            vector<bool> visited(nr_noduri, false);
            while (!visited[nod]) {
                visited[nod] = true;
                nod = parent[nod];
            }
            //Am dat de un nod in ciclu
            int stop = nod;
            nod = parent[nod];
            while (nod != stop) {
                adiac[nod][parent[nod]]++;
                adiac[parent[nod]][nod]--;
                nod = parent[nod];
            }
            adiac[nod][parent[nod]]++;
            adiac[parent[nod]][nod]--;
        nod = bellman_ford(parent);
        }
    }
    int used_edges_cost(){
       int s = 0;
//       cout << "\n Used edges: \n";
       for(int i = 0; i < n; i++)
           for(int j = 0; j < n; j++)
               if(adiac[i][j + n] == 0) {
//                   cout << "(" << i + 1<< ", " << j + 1 << ")\n";
                   s += costs[i][j + n];
               }
       return s;
    }
    int bellman_ford(vector<int>& parent){
        //Returns starting vertice for negative cycle or -1 if no such cycle exists
        //Also changes parent vector according to bellman ford relaxations
        fill(parent.begin(), parent.end(), -1);
        int curent;
        vector<int> dist(nr_noduri, infinity), len(nr_noduri, 0);
        vector<bool> in_queue(nr_noduri, false);
        queue<int> coada;
        coada.push(0);
        dist[0] = 0;
        while(!coada.empty()){
            curent = coada.front();
            coada.pop();
            in_queue[curent] = false;
            for(auto& v : adiac[curent]){
                if(v.second > 0){
                    if(dist[v.first] > dist[curent] + costs[curent][v.first]){
                        dist[v.first] = dist[curent] + costs[curent][v.first];
                        parent[v.first] = curent;
                        len[v.first]++;
                        if(len[v.first] >= 5){
                            //Exista un ciclu
                            return v.first;
                        }
                        if(!in_queue[v.first])
                            coada.push(v.first);
                    }
                }
            }
        }
        return -1;
    }
};
int main() {
    Graph graf;
    graf.bad_matching();
    graf.cancel_negative_cycles();
    g << graf.used_edges_cost();
    return 0;
}