Cod sursa(job #47226)

Utilizator stef2nStefan Istrate stef2n Data 3 aprilie 2007 14:26:51
Problema Cc Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.66 kb
#include <cstdio>
#include <deque>
using namespace std;

#define infile "cc.in"
#define outfile "cc.out"
#define NMAX 205
#define INF 100000000
struct NOD {short int x,cost; NOD *adr;};

FILE *fin,*fout;
NOD *prim[NMAX];
short int cap[NMAX][NMAX];
int N,oldN;
int cost_minim;
int cost[NMAX],prec[NMAX];
bool used[NMAX];
deque <int> coada;

inline int adaug_st(NOD *(&prim), short int x, short int cost)
  {
   NOD *a=new NOD;
   a->x=x;
   a->cost=cost;
   a->adr=prim;
   prim=a;
  }

void read_data()
  {
   int i,j,c;
   fin=fopen(infile,"r");
   fscanf(fin,"%d",&N);
   for(i=0;i<2*N+2;i++)
      prim[i]=NULL;
   // se stabilesc capacitatile si costurile
   for(i=1;i<=N;i++)
      {
       cap[0][i]=1,cap[i][0]=0;
       adaug_st(prim[0],i,0);
       adaug_st(prim[i],0,0);
      }
   for(i=N+1;i<=2*N;i++)
      {
       cap[i][2*N+1]=1,cap[2*N+1][i]=0;
       adaug_st(prim[i],2*N+1,0);
       adaug_st(prim[2*N+1],i,0);
      }
   for(i=1;i<=N;i++)
      for(j=N+1;j<=2*N;j++)
         {
          cap[i][j]=1,cap[j][i]=0;
          fscanf(fin,"%d",&c);
          adaug_st(prim[i],j,c);
          adaug_st(prim[j],i,-c);
         }
   oldN=N;
   N=2*N+2;
   fclose(fin);
  }

void bellman_ford()
  {
   int i,first;
   NOD *b;
   for(i=1;i<N;i++)
      {
       cost[i]=INF;
       used[i]=false;
      }
   cost[0]=0;
   used[0]=true;
   prec[0]=-1;
   coada.clear();
   coada.push_back(0);
   while(!coada.empty())
        {
         first=coada.front();
         b=prim[first];
         while(b)
              {
               if(cap[first][b->x] && cost[b->x]>cost[first]+b->cost)
                 {
                  cost[b->x]=cost[first]+b->cost;
                  prec[b->x]=first;
                  if(!used[b->x])
                    {
                     used[b->x]=true;
                     coada.push_back(b->x);
                    }
                 }
               b=b->adr;
              }
         used[first]=false;
         coada.pop_front();
        }
  }

void solve()
  {
   int u,v;
   do{
      bellman_ford();
      if(cost[N-1]!=INF)
        {
         u=prec[N-1];
         v=N-1;
         while(u!=-1)
              {
               cap[u][v]--;
               cap[v][u]++;
               v=u;
               u=prec[u];
              }
        }
     }while(cost[N-1]!=INF);
  }

void compute_sol()
  {
   cost_minim=0;
   N=oldN;
   for(int i=1;i<=N;i++)
      {
       NOD *b=prim[i];
       while(b)
            {
             if(b->x>N && !cap[i][b->x])
               cost_minim+=b->cost;
             b=b->adr;
            }
      }
  }


int main()
{
read_data();
solve();
compute_sol();
fout=fopen(outfile,"w");
fprintf(fout,"%d\n",cost_minim);
fclose(fout);
return 0;
}