Pagini recente » Cod sursa (job #2040933) | Cod sursa (job #493391) | Cod sursa (job #1969971) | Cod sursa (job #1133630) | Cod sursa (job #886057)
Cod sursa(job #886057)
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <set>
#include <queue>
#include <deque>
using namespace std;
ifstream f("cmcm.in");
ofstream g("cmcm.out");
#define nmax 301*2
#define Mmax 50000
#define ll long long
#define inf (1<<30)
int n, m, E, Cost[nmax][nmax], capac[nmax][nmax], Muchie[nmax][nmax], dist[nmax];
int flux[nmax][nmax];
vector<int> gf[nmax];
int q[nmax*Mmax];
bool viz[nmax];
int t[nmax];
void citeste(){
f >> n >> m >> E;
int x, y, z;
for(int i=1; i<=E; ++i){
f >> x >> y >> z;
y += n; gf[x].push_back(y);
gf[y].push_back(x);
Cost[x][y] = z;
Cost[y][x] = -z;
capac[x][y] = 1;
Muchie[x][y] = i;
}
}
inline int Bf(int S, int D){
for(int i=0; i<=n+m+1; ++i) t[i] = 0, viz[i] = 0, dist[i] = inf;
int st = 1; int dr = 1;
q[1] = S; viz[S] = 1;// e in coada
dist[S] = 0;
for(; st<=dr; ){
int nod = q[st]; ++st;
viz[nod] = 0;// l-am scos din coada
for(int i=0; i<gf[nod].size(); ++i){
int vc = gf[nod][i];
if ( flux[nod][vc] < capac[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(){
// am reindexat nodurile din a 2 multime iar apoi mai adaug o sursa si o destinatie si bag un flux maxim de cost minim
int S = 0;
for(int i=1; i<=n; ++i){
gf[S].push_back(i);
gf[i].push_back(S);
capac[S][i] = 1;
}
int D = n + m + 1;
for(int i=n+1; i<=n+m; ++i){
gf[i].push_back(D);
gf[D].push_back(i);
capac[i][D] = 1;
}
int Flux = 0; int CostMin = 0;
for(int ok=1; ok==1; ){
int CostDrum = Bf(S, D); if (CostDrum == inf) break;// daca numai exista drumuri din sursa la destinatie ; ma opresc
// aleg muchia minima
int Min = inf;
for(int i=D; i!=S; i=t[i]){
// am flux pe muhia t[i] -> i;
Min = min(Min, capac[ t[i] ][i] - flux[ t[i] ][i]);
}
// bag fluxul
for(int i=D; i!=S; i=t[i]){
flux[ t[i] ][i] += Min;
flux[ i ][ t[i] ] -= Min; // il intorc
}
Flux += Min; CostMin += CostDrum;
}
//cout << Flux << " " << CostMin << "\n";
g << Flux << " " << CostMin << "\n";
for(int i=1; i<=n; ++i){
for(int j=n+1; j<=n+m; ++j){
if (flux[i][j] > 0){
//cout << Muchie[i][j] << " ";
g << Muchie[i][j] << " ";;
}
}
}
}
int main(){
citeste();
rezolva();
f.close();
g.close();
return 0;
}