Cod sursa(job #2020162)

Utilizator GoogalAbabei Daniel Googal Data 9 septembrie 2017 14:59:44
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.47 kb
#include <iostream>
#include <fstream>
#include <climits>
#include <vector>

using namespace std;

ifstream in("cmcm.in");
ofstream out("cmcm.out");

const int nmax = 300;
const int inf = 1000000000;

int n;
int cost[1 + nmax][1 + nmax];
int index[1 + nmax][1 + nmax];
int etu[1 + nmax], etv[1 + nmax];
int visu[1 + nmax], visv[1 + nmax];
int cuplaj[1 + nmax];

int dfs(int u1) {
  visu[u1] = 1;
  for(int v1 = 1; v1 <= n; v1++) {
    int exces = etu[u1] + etv[v1] - cost[u1][v1];
    if(visv[v1] == 0 && exces == 0) {
      visv[v1] = 1;
      if(cuplaj[v1] == 0 || dfs(cuplaj[v1]) == 1) {
        cuplaj[v1] = u1;
        return 1;
      }
    }
  }
  return 0;
}

void hungarian() {
  for(int i = 1; i <= n; i++) {
    etu[i] = -inf;
    for(int j = 1; j <= n; j++) {
      etu[i] = max(etu[i], cost[i][j]);
    }
    etv[i] = 0;
  }

  for(int i=1; i<=n; i++) { //iteratii
    while(dfs(i) == 0) {
           // cout<<":";
      //atata timp cat nu am gasit drum de augmentare, relaxez vis-urile <=> updatez etichetele
      int epsilon = inf;
      for(int j = 1; j <= n; j++)
        if(visv[j] == 0) {
          for(int k = 1; k <= n; k++) {
            if(visu[k] == 1) {
              epsilon = min(epsilon, etu[k] + etv[j] - cost[k][j]);
            }
          }
        }
      //cout<<epsilon<<endl;
      for(int j = 1; j <= n; j++) {
        if(visu[j] == 1) {
          etu[j] -= epsilon;
          visu[j] = 0;
        }
        if(visv[j] == 1) {
          etv[j] += epsilon;
          visv[j] = 0;
        }
      }
    }
  }
}

int main() {
  int nedge, m;
  in >> n >> m >> nedge;
  //rezolvam problema determinarii costului maxim

  n = max(n, m);
  for(int i = 1; i <= n; i++) {
    fill(cost[i] + 1, cost[i] + n + 1, -inf);
  }

  for(int i = 1; i <= nedge; i++) {
    int from, to, c;
    in >> from >> to >> c;
    cost[from][to] = -c;
    index[from][to] = i;
  }
  /*
  for(int i = 1; i <= n; i++) {
    for(int j = 1; j <= n; j++) {
      cout << cost[i][j] << ' ';
    }
    cout << '\n';
  }
  */
  hungarian();

  int sum = 0;
  vector<int> edges;
  for(int i = 1; i <= n; i++) {
    if(cuplaj[i] != 0 && index[cuplaj[i]][i] != 0) {
      edges.push_back(index[cuplaj[i]][i]);
      sum += cost[cuplaj[i]][i];
    }
  }

  out << edges.size() << ' ' << -sum << '\n';
  for(int i = 0; i < edges.size(); i++)
    out << edges[i] << ' ';

  in.close();
  out.close();
  return 0;
}