Cod sursa(job #1996503)

Utilizator TincaMateiTinca Matei TincaMatei Data 1 iulie 2017 18:20:06
Problema Cuplaj maxim de cost minim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.98 kb
#include <cstdio>
#include <cstring>
#include <deque>
#include <ctype.h>

#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;

const int BUFF = 4096;
int curs = BUFF - 1;

char buftea[BUFF];

char getch(FILE *fin) {
  ++curs;
  if(curs == BUFF) {
    curs = 0;
    fread(buftea, 1, BUFF, fin);
  }
  return buftea[curs];
}

int getnr(FILE *fin) {
  int nr = 0;
  bool neg = false;
  char ch = getch(fin);
  while(ch != '-' && !isdigit(ch))
    ch = getch(fin);
  if(ch == '-') {
    neg = true;
    ch = getch(fin);
  }
  while(isdigit(ch)) {
    nr = nr * 10 + ch - '0';
    ch = getch(fin);
  }
  if(neg)
    nr = -nr;
  return nr;
}

std::deque<int> q;
int top, 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];
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) {
  memset(papa, -1, sizeof(papa));
  memset(costtotal, 0x3f3f3f3f, sizeof(costtotal));
  q.push_back(0);
  inqueue[0] = true;
  costtotal[0] = 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[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(costtotal[dest] < 0x3f3f3f3f) {
    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");
  n = getnr(fin);
  m = getnr(fin);
  e = getnr(fin);
  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) {
    a = getnr(fin);
    b = getnr(fin);
    c = getnr(fin);
    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;
}