Cod sursa(job #461770)

Utilizator freak93Adrian Budau freak93 Data 8 iunie 2010 16:17:41
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.85 kb
#include<fstream>
#include<vector>
#include<queue>

using namespace std;

const char iname[]="fmcm.in";
const char oname[]="fmcm.out";
const int maxn=357;
const int inf=(1<<31)-1;

ifstream f(iname);
ofstream g(oname);

int n,m,x,y,z,w,i,j,flow,S,D,dis[maxn],dist;
int C[maxn][maxn],Cost[maxn][maxn],F[maxn][maxn];

vector<int> E[maxn];

queue<int> Q;

int heap[maxn],p,pos[maxn],k,been[maxn],A[maxn],done,fmcm;

void push(int x)
{
    int aux;
    while(dis[heap[x/2]]>dis[heap[x]])
    {
        aux=heap[x/2];
        heap[x/2]=heap[x];
        heap[x]=aux;
        pos[heap[x/2]]=x/2;
        pos[heap[x]]=x;
        x/=2;
    }
}

void pop(int x)
{
    int y=0,aux;
    while(y!=x)
    {
        y=x;
        if(y*2<=done&&dis[heap[y*2]]<dis[heap[x]])
            x=y*2;
        if(y*2+1<=done&&dis[heap[y*2+1]]<dis[heap[x]])
            x=y*2+1;
        aux=heap[x];heap[x]=heap[y];heap[y]=aux;
        pos[heap[x]]=x;
        pos[heap[y]]=y;
    }
}

void bellman()
{
    for(int i=1;i<=n;++i)
        dis[i]=inf;
    memset(been,0,sizeof(been));
    been[S]=1;
    dis[S]=0;
    Q.push(S);
    int x;
    while(!Q.empty())
    {
        x=Q.front();
        Q.pop();
        been[x]=0;
        if(x==D)
            continue;
        for(vector<int>::iterator it=E[x].begin();it!=E[x].end();++it)
            if(F[x][*it]<C[x][*it]&&dis[x]+Cost[x][*it]<dis[*it])
            {
                dis[*it]=dis[x]+Cost[x][*it];
                if(been[*it]==0)
                    been[*it]=1,Q.push(*it);
            }
    }
    dist=dis[D];
}

int dijkstra()
{
    for(int i=1;i<=n;++i)
        for(vector<int>::iterator it=E[i].begin();it!=E[i].end();++it)
            if(dis[i]!=inf&&dis[*it]!=inf)
                Cost[i][*it]+=dis[i]-dis[*it];

    for(int i=1;i<=n;++i)
        heap[i]=i,pos[i]=i,A[i]=-1,dis[i]=inf;
    heap[1]=S;heap[S]=1;
    pos[1]=S;pos[S]=1;
    done=n;
    dis[S]=0;
    A[S]=S;
    while(done>1&&dis[heap[1]]!=inf)
    {
        for(vector<int>::iterator it=E[heap[1]].begin();it!=E[heap[1]].end();++it)
            if(C[heap[1]][*it]>F[heap[1]][*it]&&dis[heap[1]]+Cost[heap[1]][*it]<dis[*it])
            {
                dis[*it]=dis[heap[1]]+Cost[heap[1]][*it];
                A[*it]=heap[1];
                push(pos[*it]);
            }
        heap[1]=heap[done--];
        pos[heap[1]]=1;
        pop(1);
    }
    if(dis[D]!=inf)
    {
        int mint=inf;
        for(int i=D;i!=S;i=A[i])
            mint=min(mint,C[A[i]][i]-F[A[i]][i]);

        for(int i=D;i!=S;i=A[i])
            F[A[i]][i]+=mint,F[i][A[i]]-=mint;
        dist+=dis[D];
        return mint*dist;
    }
    return inf;
}

int main()
{
    f>>n>>m>>S>>D;
    for(i=1;i<=m;++i)
    {
        f>>x>>y>>z>>w;
        E[x].push_back(y);
        E[y].push_back(x);
        C[x][y]=z;
        Cost[y][x]=-(Cost[x][y]=w);
    }

    bellman();
    while((i=dijkstra())!=inf)
        fmcm+=i;

    g<<fmcm<<"\n";
}