Cod sursa(job #1996148)

Utilizator TincaMateiTinca Matei TincaMatei Data 30 iunie 2017 12:40:28
Problema Cuplaj maxim de cost minim Scor 60
Compilator cpp Status done
Runda Arhiva educationala Marime 2.51 kb
#include <cstdio>
#include <deque>

#warning POPA SI POLITIA, TOT LA POARTA LOR SA STEA, AMBULANTA SI MASCATII, POMPIERII SI SOLDATII

const int MAX_N = 300;
const int MAX_M = 50000;
const int MAX_MUCHII = 2 * (2 * MAX_N + MAX_M);
const int MAX_NODURI = 2 + 2 * MAX_N;
const int INF = 1000000000;

int top = 0;
int mc[1+MAX_MUCHII], next[1+MAX_MUCHII], cost[1+MAX_MUCHII],
    other[1+MAX_MUCHII], idmc[1+MAX_MUCHII];
bool flow[1+MAX_MUCHII];
int last[1+MAX_NODURI], papa[1+MAX_NODURI], papamc[1+MAX_NODURI], costtotal[1+MAX_NODURI];
bool inqueue[1+MAX_NODURI];

int flux, costflux;

std::deque<int> q;

bool pump(int src, int dest) {
  int n = dest;
  if(papa[dest] == -1)
    return false;
  ++flux;
  costflux += costtotal[dest];
  while(n != src) {
    int i = papamc[n];
    flow[i] ^= 1;
    flow[other[i]] ^= 1;
    n = papa[n];
  }
  return true;
}

bool bellman(int src, int dest) {
  q.push_back(src);
  costtotal[src] = 0;
  while(!q.empty()) {
    int nod = q.front();
    q.pop_front();
    inqueue[nod] = false;
    for(int i = last[nod]; i != 0; i = next[i]) {
      if(!flow[i] && costtotal[nod] + cost[i] < costtotal[mc[i]]) {
        costtotal[mc[i]] = costtotal[nod] + cost[i];
        if(!inqueue[mc[i]]) {
          q.push_back(mc[i]);
          inqueue[mc[i]] ^= 1;
        }
        papa[mc[i]] = nod;
        papamc[mc[i]] = i;
      }
    }
  }
  return pump(src, dest);
}

void addm(int a, int b, int c, int d, int id, int i, bool fl) {
  mc[id] = b;
  cost[id] = c;
  idmc[id] = i;
  other[id] = d;
  next[id] = last[a];
  last[a] = id;
  flow[id] = fl;
}

void addpair(int a, int b, int c, int i = -1) {
  ++top;
  addm(a, b, c, top + 1, top, i + 1, false);
  ++top;
  addm(b, a, -c, top - 1, top, 0, true);
}

int main() {
  int n, m, e, a, b, c, dest;
  FILE *fin = fopen("cmcm.in", "r");
  fscanf(fin, "%d%d%d", &n, &m, &e);
  dest = n + m + 1;
  for(int i = 0; i < e; ++i) {
    fscanf(fin, "%d%d%d", &a, &b, &c);
    b = b + n;
    addpair(a, b, c, i);
  }
  for(int i = 1; i <= n; ++i)
    addpair(0, i, 0);
  for(int i = 1; i <= m; ++i)
    addpair(i + n, dest, 0);
  fclose(fin);

  do {
    for(int i = 0; i <= dest; ++i) {
      papa[i] = papamc[i] = -1;
      costtotal[i] = INF;
    }
  } while(bellman(0, dest));

  FILE *fout = fopen("cmcm.out", "w");
  fprintf(fout, "%d %d\n", flux, costflux);
  for(int i = 1; i <= top; ++i)
    if(flow[i] && idmc[i] > 0)
      fprintf(fout, "%d ", idmc[i]);
  fclose(fout);
  return 0;
}