Cod sursa(job #805967)

Utilizator costyv87Vlad Costin costyv87 Data 1 noiembrie 2012 15:39:05
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.57 kb
#include <cstdio>
#include <vector>
#define INF 10000000
#define df(i,j) a[i][j].cap-a[i][j].fl
using namespace std;
FILE *f,*g;

struct cp{int cap,fl,z;} ;  // flux//
cp a[360][360];
int tt[360];
vector <int> e[360];
int dist[360];
int H[360],pos[360]; // Heap-ul si pozitia in Heap//
bool inq[360]; //Bellman Ford cu coada//
int  con[360]; //Bellman Ford cu coada //
int sum,sol,n,m,s,d,l,ax,x,y,c,z;

void down(int x)
{
     int y=0;

     while (x!=y )
     {
          y=x;
          if (y*2<=l && dist[H[x]]>dist[H[2*y]]) x=y*2;
          if (y*2+1<=l && dist[H[x]]>dist[H[2*y+1]]) x=y*2+1;

          ax=H[x], H[x]=H[y], H[y]=ax;
          pos[H[x]]=x, pos[H[y]]=y;
     }
}


void up(int x)
{
     int ax;

     while (x/2>0 && dist[H[x]]<dist[H[x/2]])
     {
          ax=pos[H[x]],pos[H[x]]=pos[H[x/2]],pos[H[x/2]]=ax;
          ax=H[x],H[x]=H[x/2],H[x/2]=ax;
          x/=2;
     }
}


void bellman_ford()
{
     int i,j,x,nm=n*m;
     vector <int> q;
     bool ok;

     for (i=1;i<=n;i++) dist[i]=INF;
     dist[s]=0;
     inq[s]=true;
     q.push_back(s);


     for (ok=false,i=0;i<q.size() && ok==false;i++)
     {
          x=q[i];
          inq[x]=false;
          for (j=0;j<e[x].size();j++)
               if ( df(x,e[x][j])>0 && dist[x]+a[x][e[x][j]].z<dist[e[x][j]])
               {
                    dist[e[x][j]]=dist[x]+a[x][e[x][j]].z;
                    if (inq[e[x][j]]==false)
                    {
                         if (con[e[x][j]]>n)
                              ok=true;
                         else
                         {
                              q.push_back(e[x][j]);
                              inq[e[x][j]]=true;
                              con[e[x][j]]++;
                         }

                    }
               }
     }

     sum=dist[d];
}


void cut()
{
     H[1]=H[l--];
     pos[H[1]]=1;
     down(1);
}

int dijkstra()
{
     int i,j,mn;

     for (i=1;i<=n;i++)
          for (j=0;j<e[i].size();j++)
               if (dist[i]<INF && dist[e[i][j]]<INF)
                    a[i][e[i][j]].z+=dist[i]-dist[e[i][j]];

     for (i=1;i<=n;i++)
     {
          dist[i]=INF;
          tt[i]=-1;
          H[i]=i;
          pos[i]=i;
     }

     H[1]=s; H[s]=1;
     pos[H[1]]=1, pos[H[s]]=s;
     dist[s]=0;

     for (l=n;l>1 && dist[H[1]]!=INF;)
     {
          i=H[1];

          for (j=0;j<e[i].size();j++)
               if (df(i,e[i][j])>0 && dist[i]+a[i][e[i][j]].z<dist[e[i][j]])
               {
                    dist[e[i][j]]=dist[i]+a[i][e[i][j]].z;
                    tt[e[i][j]]=i;
                    up(pos[e[i][j]]);

               }
          cut();
     }


     if (tt[d]!=-1)
     {
          for (mn=INF,i=d;i!=s;i=tt[i])
               mn=min(mn,df(tt[i],i));

          for (i=d;i!=s;i=tt[i])
          {
               a[tt[i]][i].fl+=mn;
               a[i][tt[i]].fl-=mn;
          }

          sum+=dist[d];
          sol=sol+(sum*mn);

          return 1;
     }
     else
          return 0;
}

int flux()
{
     while (dijkstra()) ;
     return sol;
}

int main()
{
     f=fopen("fmcm.in","r");
     g=fopen("fmcm.out","w");

     fscanf(f,"%d%d%d%d",&n,&m,&s,&d);

     for (int i=1;i<=m;i++)
     {
          fscanf(f,"%d%d%d%d",&x,&y,&c,&z);
          e[x].push_back(y);
          e[y].push_back(x);
          a[x][y].z=z;
          a[x][y].cap=c;
          a[y][x].z=-z;
     }

     bellman_ford();

     fprintf(g,"%d",flux());


     fclose(g);
     return 0;
}