Cod sursa(job #2020226)

Utilizator GoogalAbabei Daniel Googal Data 9 septembrie 2017 17:09:25
Problema Cc Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.08 kb
#include <iostream>
#include <fstream>

using namespace std;

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

const int NMAX = 100;
const int DIM = 1000000;
const int INF = 1 << 25;

int n, res, pos;
int cost[1 + NMAX][1 + NMAX];
int etu[1 + NMAX], etv[1 + NMAX];
int visu[1 + NMAX], visv[1 + NMAX];
int cuplaj[1 + NMAX];
char buff[DIM];

int read(){
  int no = 0;
  while(!isdigit(buff[pos])){
    if(++pos == DIM){
      in.read(buff, DIM);
      pos = 0;
    }
  }

  while(isdigit(buff[pos])){
    no = (no * 10) + (buff[pos] - '0');
    if(++pos == DIM){
      in.read(buff, DIM);
      pos = 0;
    }
  }

  return no;
}

bool 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;
    etv[i] = 0;
    for(int j = 1; j <= n; j++) {
      etu[i] = max(etu[i], cost[i][j]);
    }
  }

  for(int i = 1; i <= n; i++) {
    while(dfs(i) == 0) {
      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]);
          }
        }
      }
      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()
{
  //in >> n;
  n = read();
  for(int i = 1; i <= n; i++) {
    for(int j = 1; j <= n; j++) {
      //in >> cost[i][j];
      cost[i][j] = read();
      cost[i][j] *= -1;
    }
  }
  hungarian();

  for(int i = 1; i <= n; i++) {
    if(cuplaj[i] != 0)
      res += cost[cuplaj[i]][i];
  }

  out << -res << '\n';
  in.close();
  out.close();
  return 0;
}