Cod sursa(job #934792)

Utilizator vendettaSalajan Razvan vendetta Data 31 martie 2013 14:39:22
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.52 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <queue>

using namespace std;

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

#define nmax 301
#define Mmax 50005
#define inf (1<<30)

int n, m, E, capac[2*nmax][2*nmax], cost[2*nmax][2*nmax];
pair<int,int> Edge[Mmax];
int flux[nmax*2][nmax*2], t[nmax*2], inCoada[nmax*2], dist[nmax*2];
queue<int> q;
vector<int> gf[nmax*2];

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;
      Edge[i] = make_pair(x, y);
   }
}

void bagaS(int S){
   for(int i=1; i<=n; ++i){
      gf[i].push_back(S);
      gf[S].push_back(i);
      capac[S][i] = 1;
   }
}

void bagaD(int D){
   for(int i=n+1; i<=n+m; ++i){
      gf[i].push_back(D);
      gf[D].push_back(i);
      capac[i][D] = 1;
   }
}

int Bf(int S, int D){
   for(int i=0; i<=D; ++i) inCoada[i] = 0, dist[i] = inf;
   q.push(S); inCoada[S] = 1;
   dist[S] = 0;

   for(; q.size(); ){
      int nod = q.front(); q.pop();
      inCoada[nod] = 0;
      for(int i=0; i<gf[nod].size(); ++i){
         int vc = gf[nod][i];
         if (dist[vc] > dist[nod] + cost[nod][vc] && capac[nod][vc] > flux[nod][vc]){
            dist[vc] = dist[nod] + cost[nod][vc];
            t[vc] = nod;
            if (inCoada[vc] == 0){
               inCoada[vc] = 1;
               q.push(vc);
            }
         }
      }
   }

   return dist[D];
}

void bagaFlux(){
   int S = 0; int D = n + m +1; int costTot = 0; int Cuplaj = 0;
   for(int ok=1; ok!=0;){
      int Cost = Bf(S, D);
      if( Cost == inf) break;
      int Min = inf;
      for(int i=D; i!=S; i=t[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;
      }

      costTot += (Min * Cost);
      Cuplaj += Min;
   }

   //cout << Cuplaj << " " << costTot << "\n";
   g << Cuplaj << " " << costTot << "\n";
   for(int i=1; i<=E; ++i){
      int x = Edge[i].first; int y = Edge[i].second;
      if ( flux[x][y] > 0 || flux[y][x] > 0){
         //cout << i << " ";
         g << i << "\n";
      }
   }
   g << '\n';

}

void rezolva(){
   int S = 0;
   bagaS(0); bagaD(n+m+1);
   bagaFlux();
}

int main(){
   citeste();
   rezolva();

   f.close();
   g.close();

   return 0;

}