Pagini recente » Cod sursa (job #242538) | Cod sursa (job #2561574) | Cod sursa (job #1614749) | Cod sursa (job #1600972) | Cod sursa (job #3191176)
#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] = len[curent] + 1;
if(len[v.first] >= nr_noduri){
//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;
}