Cod sursa(job #370674)

Utilizator mgntMarius B mgnt Data 1 decembrie 2009 19:54:51
Problema Cc Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.25 kb
// Kuhn-Munkres Algorithm
// 
#include <iostream>
#include <fstream>
using namespace std;

int const maxn = 100;
int const maxw = 10 * 1000;

typedef int T1 [maxn];
typedef T1 T2 [maxn];

T2 W; int N;
T1 S,T,C,D,P,Q,A,B;

void
kuhn_munkres ( )
{
  int x,y,u,c0,c1,cm;
  cm=0;
  for ( x=0; N>x; ++x ) { C[x]=-1; }
  for ( y=0; N>y; ++y ) { D[y]=-1; }
  for ( y=0; N>y; ++y ) { B[y]=0; }
  for ( x=0; N>x; ++x ) {
    A[x]=W[x][0];
    for ( y=1; N>y; ++y ) {
      if (A[x]<W[x][y]) { A[x]=W[x][y]; }
    }
  }
  while ( N>cm ) {
    for ( x=0; -1!=C[x]; ++x ) { S[x]=0; }
    u=x; S[u]=1;
    for ( ++x; N>x; ++x ) { S[x]=0; }
    c0=0; // c0 is the size of T.
    for ( y=0; N>y; ++y ) { T[y]=0; }
    c1=0; // c1 is the size of N_l(S)
    for ( y=0; N>y; ++y ) { 
      Q[y]=A[u]+B[y]-W[u][y]; P[y]=u;
      if ( 0==Q[y] ) { ++ c1; }
    }
    bool a = false;
    while ( ! a ) {
      if ( c0 < c1 ) {
        y=0; while ( (0!=T[y]) || (0!=Q[y]) ) { ++y; }
        if ( -1 != D[y] ) {
          x=D[y]; T[y]=S[x]=1; ++c0;
          for ( y=0; N>y; ++y ) {
            if ( 0==T[y] ) {
              if ( A[x]+B[y]-W[x][y]<Q[y] ) {
                Q[y]=A[x]+B[y]-W[x][y]; P[y]=x;
                if ( 0==Q[y] ) { ++c1; }
              }
            }
          }
        } else {
          int yy;
          do {
            x=P[y]; D[y]=x; yy=C[x]; C[x]=y;
            y=yy; 
          } while ( -1 != y );
          ++cm; a=true;
        }
      } else {
        y=0; while ( 0!=T[y] ) { ++y; }
        int alpha=Q[y];
        for ( ++y; N>y; ++y ) {
          if ( (0==T[y]) && (alpha>Q[y]) ) {
            alpha=Q[y];
          }
        }
        for ( y=0; N>y; ++y ) {
          if ( 0!=T[y] ) {
            B[y]+=alpha;
          }
          else {
            Q[y]-=alpha;
            if ( 0==Q[y] ) { ++c1; }
          }
        }
        for ( x=0; N>x; ++x ) {
          if ( 0!=S[x] ) { A[x]-=alpha; }
        }
      }
    } 
  } 
}

int
main ( )
{
  ifstream is ( "cc.in" );
  ofstream os ( "cc.out" );
  is >> N;
  int x,y;
  for ( x=0; N>x; ++x ) {
    for ( y=0; N>y; ++y ) {
      is >> W[x][y]; W[x][y]=maxw-W[x][y];
    }
  }
  kuhn_munkres();
  int weight=0;
  for ( x=0; N>x; ++x ) {
    y=C[x]; weight += W[x][y];
  }
  weight=N*maxw-weight;
  os << weight << endl;
  return 0;
}