Cod sursa(job #1996398)

Utilizator TincaMateiTinca Matei TincaMatei Data 1 iulie 2017 14:06:37
Problema Cuplaj maxim de cost minim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.58 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_NODURI = 1 + MAX_N + MAX_N + 1;
const int MAX_MUCHII = MAX_N + MAX_M + MAX_N;

std::deque<int> q;
int top, it, flux, costflux;
int mc[1+2*MAX_MUCHII], next[1+2*MAX_MUCHII];
bool flow[MAX_NODURI][MAX_NODURI];
int edge[MAX_NODURI][MAX_NODURI], cost[MAX_NODURI][MAX_NODURI];
int last[MAX_NODURI], papa[MAX_NODURI], costtotal[MAX_NODURI], lastit[MAX_NODURI];
bool inqueue[MAX_NODURI];

void addM(int a, int b) {
  ++top;
  next[top] = last[a];
  last[a] = top;
  mc[top] = b;
}

bool bellman(int dest) {
  q.push_back(0);
  inqueue[0] = true;
  costtotal[0] = 0;
  ++it;
  while(!q.empty()) {
    int nod = q.front();
    q.pop_front();
    inqueue[nod] = false;
    for(int i = last[nod]; i != 0; i = next[i]) {
      if(it > lastit[mc[i]] && !flow[nod][mc[i]]) {
        lastit[mc[i]] = it;
        costtotal[mc[i]] = costtotal[nod] + cost[nod][mc[i]];
        papa[mc[i]] = nod;
        inqueue[mc[i]] = true;
        q.push_back(mc[i]);
      } else if(!flow[nod][mc[i]] && costtotal[nod] + cost[nod][mc[i]] < costtotal[mc[i]]) {
        costtotal[mc[i]] = costtotal[nod] + cost[nod][mc[i]];
        papa[mc[i]] = nod;
        if(!inqueue[mc[i]]) {
          inqueue[mc[i]] = true;
          q.push_back(mc[i]);
        }
      }
    }
  }

  if(lastit[dest] == it) {
    int nod = dest;
    flux++;
    costflux += costtotal[dest];
    while(nod != 0) {
      flow[papa[nod]][nod] ^= 1;
      flow[nod][papa[nod]] ^= 1;
      nod = papa[nod];
    }
    return true;
  }
  return false;
}

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 <= dest; ++i)
    for(int j = 0; j <= dest; ++j)
      flow[i][j] = true;
  for(int i = 1; i <= e; ++i) {
    fscanf(fin, "%d%d%d", &a, &b, &c);
    b = b + n;
    flow[a][b] = false;
    cost[a][b] = c;
    cost[b][a] = -c;
    edge[a][b] = i;
    addM(a, b);
    addM(b, a);
  }
  for(int i = 1; i <= n; ++i) {
    flow[0][i] = false;
    addM(0, i);
    addM(i, 0);
  }
  for(int i = 1; i <= m; ++i) {
    flow[i + n][dest] = false;
    addM(i + n, dest);
    addM(dest, i + n);
  }
  fclose(fin);

  while(bellman(dest));

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