Pagini recente » Cod sursa (job #1538336) | Cod sursa (job #2522891) | Cod sursa (job #1959839) | Cod sursa (job #428723) | Cod sursa (job #886183)
Cod sursa(job #886183)
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <set>
#include <queue>
#include <deque>
using namespace std;
ifstream f("cc.in");
ofstream g("cc.out");
#define nmax 102*2
#define ll long long
#define inf (1<<30)
int n, cost[nmax][nmax], capac[nmax][nmax], flux[nmax][nmax];
int t[nmax], dist[nmax];
vector<int> gf[nmax];
bool viz[nmax];
int q[nmax*nmax*nmax];
void citeste(){
f >> n;
int x,y;
for(int i=1; i<=n; ++i){
for(int j=1; j<=n; ++j){
x = i; y = j + n;
gf[x].push_back(y);
gf[y].push_back(x);
f >> cost[x][y];
cost[y][x] = -cost[x][y];
capac[x][y] = 1;
}
}
}
void bagaS(int S){
// bag muchii de genul S -> i; nodurile fiind din priam multime
for(int i=1; i<=n; ++i){
gf[S].push_back(i);
gf[i].push_back(S);
capac[S][i] = 1;
}
}
void bagaD(int D){
// muchie de genul i-> D; nodurile fiind din a 2 multime
for(int i=n+1; i<=2*n; ++i){
gf[i].push_back(D);
gf[D].push_back(i);
capac[i][D] = 1;
}
}
inline int Bf(int S, int D){
for(int i=0; i<=D; ++i) t[i] = 0, viz[i] = 0, dist[i] = inf;
int st = 1; int dr = 0;
q[++dr] = S; viz[S] = 1;
dist[S] = 0;
for(; st<=dr; ){
int nod = q[st]; ++st;
viz[nod] = 0;// l-am scos
for(int i=0; i<gf[nod].size(); ++i){
int vc = gf[nod][i];
if ( capac[nod][vc] > flux[nod][vc] && dist[vc] > dist[nod] + cost[nod][vc] ){
dist[vc] = dist[nod] + cost[nod][vc];
t[vc] = nod;
if (viz[vc] == 0){
viz[vc] = 1;
q[++dr] = vc;
}
}
}
}
return dist[D];
}
void rezolva(){
// fac un graf bipartit dupa care nodurile din a 2 -a multimea le reindexez si bag un cuplaj maxim de cost minim
// bag sursa si destinatia
int S = 0; int D = n *2 + 1;
bagaS(0); bagaD(n*2+1);
int CostMin = 0;
for(int ok=1; ok==1;){
int CostDrum = Bf(S, D); if (CostDrum == inf) break;// daca nu am reusit sa ajung in destinatie
// aleg fluxil minim pe care il pot baga pe drumu curent
int Min = inf;
for(int i=D; i!=S; i=t[i]){
// vreau sa bag pe t[i]->i;
Min = min(Min, capac[ t[i] ][i] - flux[ t[i] ][i]);
}
for(int i=D; i!=S; i=t[i]){
flux[ t[i] ][i] += Min;
flux[i][ t[i] ] -= Min;
}
CostMin += CostDrum;
}
cout << CostMin << "\n";
g << CostMin << "\n";
}
int main(){
citeste();
rezolva();
f.close();
g.close();
return 0;
}