Cod sursa(job #87774)

Utilizator VmanDuta Vlad Vman Data 29 septembrie 2007 01:15:07
Problema Algola Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.91 kb
using namespace std;
#include <stdio.h>
#include <string.h>
#include <vector>

#define Nmax 64
#define Tmax 128
#define codifica(a,b) ( (b) * 64 + (a) )

int N,M,T,flow;
int cap[Nmax][Nmax];
vector<int> g[Nmax];
int C[Nmax*Tmax][Nmax*Tmax];
int A[Nmax],sum;
int coada[Nmax*Tmax],p[Nmax*Tmax];

inline int minim(int a,int b) { return a<b?a:b; }

void citire()
{
 int x,y,l,i;
 freopen("algola.in","r",stdin);
 scanf("%d %d",&N,&M);
 for (i=1;i<=N;++i)
     {
      scanf("%d",&A[i]);
      if (A[i])
         {
          sum+=A[i];
          cap[0][i]=cap[i][0]=A[i];
          g[0].push_back(i);
//          g[i].push_back(0);
         }
     }
 for (i=0;i<M;++i)
     {
      scanf("%d %d %d",&x,&y,&l);
      cap[x][y]=cap[y][x]=l;
      g[x].push_back(y);
      g[y].push_back(x);
     }
 fclose(stdin);
}

int bfs()
{
 int st,dr,nod,t,timp=0,min;
 vector<int>::iterator it;
 coada[st=dr=0]=0;
 memset(p,-1,sizeof(p));
 while ((st<=dr)&&(timp==0))
       {
        //decodifica
        nod=coada[st]%Nmax;
        t=coada[st]/Nmax;
        //parcurge vecinii
        for (it=g[nod].begin();it<g[nod].end() && timp==0;++it)
            {
             if ((t<T)&&( p[codifica(*it,t+1)] == -1 )&&( C[coada[st]][codifica(*it,t+1)]>0 ))
               {
                coada[++dr]=codifica(*it,t+1);
                p[coada[dr]]=coada[st];
                if (*it==1) { timp=t+1;break; }
               }
             if ((t)&&( p[codifica(*it,t-1)] == -1 )&&( C[coada[st]][codifica(*it,t-1)]>0 ))
               {
                coada[++dr]=codifica(*it,t-1);
                p[coada[dr]]=coada[st];
                if (*it==1) { timp=t-1;break; }
               }
            }
        if (p[codifica(nod,t+1)]==-1) { coada[++dr]=codifica(nod,t+1);p[coada[dr]]=coada[st]; }
       ++st;
       }
        if (timp==0) return 0;
        //minimul din drum
        nod=codifica(1,timp);
        min=sum;
        while (p[nod]!=-1)
              {
               min=minim(min,C[p[nod]][nod]);
               nod=p[nod];
              }
        flow+=min;
        nod=codifica(1,timp);
        while (p[nod]!=-1)
              {
               C[nod][p[nod]]+=min;
               C[p[nod]][nod]-=min;
               nod=p[nod];
              }
 return 1;
}

void flux()
{
 vector<int>::iterator it;
 int t,i;
 //construiesc grafu
 for (t=1;t<Tmax;++t)
  for (i=1;i<=N;++i)
  {
   C[codifica(i,t)][codifica(i,t+1)]=sum;
   for (it=g[i].begin();it<g[i].end();++it)
      {
       C[codifica(i,t)][codifica(*it,t+1)]=cap[i][*it];
       //C[codifica(*it,t-1)][codifica(i,t)]=cap[i][*it];
      }
  }
 for (it=g[0].begin();it<g[0].end();++it)
     C[0][codifica(*it,1)]=cap[0][*it];
 //Edmonds-Karp
 for (T=1;flow<sum;++T)
   while (bfs());
}

int main()
{
 citire();
 flux();
 freopen("algola.out","w",stdout);
 printf("%d",T-2);
 fclose(stdout);
 return 0;
}