Cod sursa(job #875278)

Utilizator vlad_DVlad Dumitriu vlad_D Data 9 februarie 2013 21:08:44
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2 kb
#include <cstdio>
#include <algorithm>
#include <string.h>

using namespace std;
namespace cupc {
int n, m, e;
#define nods 301
int v[nods][nods];
int g[nods][nods];
int r[nods], l[nods];
int vr[nods], vc[nods];
int cr[nods], cc[nods];
int p[nods];
void find_zero() {
  int i, j, mn;
  for (mn = 1<<30, i = 1; i <= n; ++i) if (!cr[i])
    for (j = 1; j <= n; ++j) if (!cc[j])
      mn = min(g[i][j] + vr[i] + vc[j], mn);
  for (i = 1; i <= n; ++i) {
    if (cr[i]) vr[i] += mn;
    if (!cc[i]) vc[i] -= mn;
  }
  for (i = 1; i <= n; ++i) if (!cr[i])
    for (j = 1; j <= n; ++j) if (!cc[j] && g[i][j] + vr[i] + vc[j] == 0) {
      if (r[i]) {
        p[i] = j; cr[i] = 1; cc[r[i]] = 0;
        break;
      } else {
        int aux;
        do {aux = l[j]; r[i] = j; l[j] = i; i = aux; j = p[i];}
        while (aux);
        return;
      }
    }
  find_zero();
}
void clear() {
  n = m = e = 0;
  memset(v, 0, sizeof(v)); memset(g, 0, sizeof(g)); memset(r, 0, sizeof(r)); memset(l, 0, sizeof(l));
  memset(vr, 0, sizeof(vr)); memset(vc, 0, sizeof(vc)); memset(cr, 0, sizeof(cr)); memset(cc, 0, sizeof(cc));
  memset(p, 0, sizeof(p));
}
void adapt();
};  // cuplacj de cost minim
namespace in {
int N, M, E;
int EE[50001][3];
}
using namespace in;
int main() {
  freopen("cmcm.in", "r", stdin);
  freopen("cmcm.out", "w", stdout);
  scanf("%d %d %d", &N, &M, &E);
  for (int i = 1; i <= E; ++i) scanf("%d %d %d", &EE[i][0], &EE[i][1], &EE[i][2]);
  cupc::adapt();
  return 0;
}
void cupc::adapt() {
  n = max(N, M);
  for (int i = 1; i <= E; ++i) {
    v[EE[i][0]][EE[i][1]] = i;
    g[EE[i][0]][EE[i][1]] = EE[i][2] - 20001;
  }
  for (int cnt = 0; cnt < n; ++cnt) {
    for (int i = 1; i <= n; ++i) {
        cr[i] = p[i] = 0;
        cc[i] = l[i];
    }
    find_zero();
  }
  int nr = 0, k = 0;
  for (int i = 1; i <= n; ++i) if (r[i] && v[i][r[i]]) {
    ++nr;
    k+= g[i][r[i]] + 20001;
  }
  printf("%d %d\n", nr, k);
  for (int i = 1; i <= n; ++i) if (r[i] && v[i][r[i]]) {
    printf("%d ", v[i][r[i]]);
  }
  if (nr) printf("\n");
}