Cod sursa(job #484466)

Utilizator Pepelea_FlaviuFlaviu Pepelea Pepelea_Flaviu Data 14 septembrie 2010 16:30:23
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.7 kb
# include <cstdio>
# include <queue>
# include <vector>
# include <algorithm>

using namespace std;

# define FIN "cmcm.in"
# define FOUT "cmcm.out"

const int MAX_N = 605;

# define f first
# define s second
# define pb push_back
# define mp make_pair
# define inf 0x3f3f3f3f

int N, M, E, i, j, S, D;
queue<int> Q;
int T[MAX_N];
int Dist[MAX_N];
bool used[MAX_N];
int C[MAX_N][MAX_N];
vector <pair <int, int> > G[MAX_N];

    bool Bellman() {
        vector <pair <int, int> > :: iterator it;
        
        memset(T, -1, sizeof(T));
        memset(Dist, inf, sizeof(Dist));
        memset(used, false, sizeof(used));
        used[S] = true; Q.push(S); Dist[S] = 0;
        
        while (!Q.empty()) {
              used[Q.front()] = false;
              for (it = G[Q.front()].begin(); it != G[Q.front()].end(); ++it)
                  if (C[Q.front()][it -> f] && Dist[Q.front()] + it -> s < Dist[it -> f]) {
                     
                      T[it -> f] = Q.front();
                      Dist[it -> f] = Dist[Q.front()] + it -> s;
                      
                      if (!used[it -> f]) {
                         Q.push(it -> f);
                         used[it -> f] = true;
                      }
                  }
              
              Q.pop();
        }
        
        return Dist[D] == inf ? false : true;
    }

    void Flow() {
         int flow = 0, cost = 0;
         
         while (Bellman()) {
               ++flow; cost += Dist[D];
               for (int cur = D; T[cur] != -1; cur = T[cur]) {
                   C[cur][T[cur]] = C[T[cur]][cur];
                   C[T[cur]][cur] = 0;
               }
         }
         
         printf("%d %d\n", flow, cost);
         for (i = 1; i <= N; ++i)
            for (j = N + 1; j <= N + M; ++j)
               if (!C[i][j] && C[j][i]) printf("%d ", C[j][i]);
    }

    int main() {
        freopen(FIN, "r", stdin);
        freopen(FOUT, "w", stdout);
        
        scanf("%d%d%d", &N, &M, &E);
        
        int p, q, c;
        for (i = 1; i <= E; ++i) {
            scanf("%d%d%d", &p, &q, &c);
            
            G[p].pb(mp(N + q, c));
            G[N + q].pb(mp(p, -c));
            
            C[p][N + q] = i;
        }
        
        S = 0; D = N + M + 1;
        for (i = 1; i <= N; ++i) {
            G[S].pb(mp(i, 0));
            G[i].pb(mp(S, 0));
            
            C[S][i] = 1;
        }
        
        for (i = 1; i <= M; ++i) {
            G[N + i].pb(mp(D, 0));
            G[D].pb(mp(N + i, 0));
            
            C[N + i][D] = 1;
        }
        
        Flow();
        
        return 0;
    }