Cod sursa(job #1655694)

Utilizator hrazvanHarsan Razvan hrazvan Data 18 martie 2016 11:07:12
Problema Cuplaj maxim de cost minim Scor 50
Compilator c Status done
Runda Arhiva educationala Marime 2.18 kb
#include <stdio.h>
#include <string.h>
#define MAXN 300
#define MAXM 50000
#define INF 2000000000
int nd[2 * MAXM + 4 * MAXN], nxt[2 * MAXM + 4 * MAXN], cost[2 * MAXM + 4 * MAXN], cpc[2 * MAXM + 4 * MAXN], fol[2 * MAXM + 4 * MAXN], ut[2 * MAXN + 2], dr;
int n;
int dist[2 * MAXN + 2], prev[2 * MAXN + 2], mch[2 * MAXN + 2], q[MAXN * MAXN];

inline int min2(int a, int b){
  return a < b ? a : b;
}

inline void add(int x, int y, int c, int ct){
  nd[dr] = y;
  nxt[dr] = ut[x];
  cpc[dr] = c;
  cost[dr] = ct;
  ut[x] = dr;
  dr++;
}

inline char bell(int s, int d){
  memset(dist, 0x7f, sizeof dist);
  int dq = 1, sq = 0, poz;
  q[0] = s;
  dist[s] = 0;
  while(sq < dq){
    poz = ut[q[sq]];
    while(poz != -1){
      if(cpc[poz] - fol[poz] > 0 && dist[nd[poz]] > dist[q[sq]] + cost[poz]){
        q[dq] = nd[poz];
        dist[nd[poz]] = dist[q[sq]] + cost[poz];
        prev[nd[poz]] = q[sq];
        mch[nd[poz]] = poz;
        dq++;
      }
      poz = nxt[poz];
    }
    sq++;
  }
  return dist[d] < INF;
}

int main(){
  FILE *in = fopen("cmcm.in", "r");
  int a, b, m, i, x, y, z;
  fscanf(in, "%d%d%d", &a, &b, &m);
  memset(ut, -1, sizeof ut);
  for(i = 0; i < m; i++){
    fscanf(in, "%d%d%d", &x, &y, &z);
    x--;  y--;
    y += a;
    add(x, y, 1, z);
    add(y, x, 0, -z);
  }
  fclose(in);
  int s = a + b, d = a + b + 1;
  for(i = 0; i < a; i++){
    add(s, i, 1, 0);
    add(i, s, 0, 0);
  }
  for(i = 0; i < b; i++){
    add(a + i, d, 1, 0);
    add(d, a + i, 0, 0);
  }
  int augm, rez = 0, atot = 0;
  while(bell(s, d)){
    x = d;
    augm = INF;
    while(x != s){
      augm = min2(augm, cpc[mch[x]] - fol[mch[x]]);
      x = prev[x];
    }
    atot += augm;
    x = d;
    while(x != s){
      fol[mch[x]] += augm;
      if(mch[x] & 1)
        fol[mch[x] - 1] -= augm;
      else
        fol[mch[x] + 1] -= augm;
      rez += augm * cost[mch[x]];
      x = prev[x];
    }
  }
  FILE *out = fopen("cmcm.out", "w");
  fprintf(out, "%d %d\n", atot, rez);
  for(i = 0; i < dr; i += 2){
    if(nd[i] < a + b && nd[i + 1] < a + b && fol[i] == 1)
      fprintf(out, "%d ", i / 2 + 1);
  }
  fclose(out);
  return 0;
}