Cod sursa(job #400590)

Utilizator lorandCsorba Lorand-Alexandru lorand Data 21 februarie 2010 17:45:42
Problema Flux maxim de cost minim Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 4.49 kb
using namespace std;
#include<fstream>
#define INFINIT 2147483647
int c[355][355],z1[355][355],z2[355][355],d[355],v[355],t[355],h[355],poz[355],nH,N,M,S,D,cost;
struct coada
{
       int info;
       coada* next;
};
int dijkstra();
void cerne(int);
void promoveaza(int);
int main()
{
    coada *st,*dr,*q;
    int i,x,y,cc,z,cmin;
    ifstream fin("fmcm.in");
    fin>>N>>M>>S>>D;
    for(i=1;i<=M;++i)
    {
                     fin>>x>>y>>cc>>z;
                     c[x][y]=cc;
                     z1[x][y]=z;
                     z1[y][x]=-z;
    }
    for(i=1;i<=N;++i)
       d[i]=INFINIT;
    st=new coada;
    dr=st;
    st->info=S;
    st->next=NULL;
    v[S]=1;
    d[S]=0;
    while(st)
    {
             x=st->info;
             v[x]=0;
             if(d[x]<INFINIT)
               for(i=1;i<=N;++i)
                  if(c[x][i])
                    if(d[i]>d[x]+z1[x][i])
                    {
                                          d[i]=d[x]+z1[x][i];
                                          if(v[i]==0)
                                          {
                                                     q=new coada;
                                                     dr->next=q;
                                                     dr=dr->next;
                                                     dr->info=i;
                                                     dr->next=NULL;
                                                     v[i]=1;
                                          }
                    
                    }
             q=st;
             st=st->next;
             delete q;
    }
    for(x=1;x<=N;++x)
       for(i=1;i<=N;++i)
          if(c[x][i])
            z2[x][i]=z1[x][i]+d[x]-d[i];
    while(dijkstra())
    {
                     cmin=INFINIT;
                     for(x=N;t[x];x=t[x])
                        if(c[t[x]][x]<cmin)
                          cmin=c[t[x]][x];
                     for(x=N;t[x];x=t[x])
                     {
                                         c[t[x]][x]-=cmin;
                                         c[x][t[x]]+=cmin;
                                         cost+=z1[t[x]][x]*cmin;
                     }
    }
    ofstream fout("fmcm.out");
    fout<<cost;
    return 0;
}
int dijkstra()
{
    int i,x,pmin;
    for(i=0;i<=N;++i)
    {
                     d[i]=INFINIT;
                     t[i]=-1;
                     v[i]=0;
                     h[i]=i;
                     poz[i]=i;
    }
    nH=N;
    v[S]=1;
    d[S]=t[S]=0;
    h[S]=h[nH--];
    poz[h[S]]=S;
    cerne(S);
    for(i=1;i<=N;++i)
       if(c[S][i])
       {
                  d[i]=z2[S][i];
                  t[i]=S;
                  promoveaza(poz[i]);
       }
    for(x=1;x<N;++x)
    {
                    pmin=h[1];
                    if(d[pmin]==INFINIT)
                      break;
                    v[pmin]=1;
                    h[1]=h[nH--];
                    poz[h[1]]=1;
                    cerne(1);
                    for(i=1;i<=N;++i)
                       if(c[pmin][i])
                         if(v[i]==0)
                           if(d[i]>d[pmin]+z2[pmin][i])
                           {
                                                       d[i]=d[pmin]+z2[pmin][i];
                                                       t[i]=pmin;
                                                       promoveaza(poz[i]);
                           }
    }
    if(d[D]<INFINIT)
      return 1;
    return 0;
}
void cerne(int k)
{
     int eh=0,i,aux;
     while(eh==0 && 2*k<=nH)
     {
                 i=2*k;
                 if(i+1<=N)
                   if(d[h[i]]>d[h[i+1]])
                     ++i;
                 if(d[h[k]]<=d[h[i]])
                   eh=1;
                 else
                 {
                     aux=h[i];
                     h[i]=h[k];
                     h[k]=aux;
                     poz[h[i]]=i;
                     poz[h[k]]=k;
                     k=i;
                 }
     }
}
void promoveaza(int k)
{
     int eh=0,i,aux;
     while(eh==0 && k/2)
     {
                 i=k/2;
                 if(d[h[i]]<=d[h[k]])
                   eh=1;
                 else
                 {
                     aux=h[i];
                     h[i]=h[k];
                     h[k]=aux;
                     poz[h[i]]=i;
                     poz[h[k]]=k;
                     k=i;
                 }
     }
}