Cod sursa(job #1212231)

Utilizator thewildnathNathan Wildenberg thewildnath Data 24 iulie 2014 10:49:36
Problema Flux maxim de cost minim Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.04 kb
#include<stdio.h>
#include<vector>
#include<queue>
#include<string.h>
using namespace std;

#define NMAX 352
#define INF 200000000

int n,m,sol,s,d;
int t[NMAX],f[NMAX][NMAX],val[NMAX],cost[NMAX][NMAX];

vector<int>v[NMAX];

struct cmp
{
    bool operator()(const int &a,const int &b)
    {
        return val[a]>val[b];
    }
};

priority_queue<int,vector<int>, cmp>q;

bool drum()
{
    int i,nod,fiu;

    while(!q.empty())
        q.pop();
    memset(t,0,sizeof(t));
    memset(val,0,sizeof(val));

    t[s]=s;
    val[s]=0;
    q.push(s);

    while(!q.empty())
    {
        nod=q.top();
        q.pop();

        for(i=0;i<v[nod].size();++i)
        {
            fiu=v[nod][i];

            if(f[fiu][nod] && !t[fiu] && (val[fiu]==0 || val[fiu]>val[nod]+cost[nod][fiu]))
            {
                t[fiu]=nod;
                val[fiu]=val[nod]+cost[nod][fiu];

                if(fiu==d)
                    return 1;

                q.push(fiu);
            }
        }
    }

    return 0;
}

int main()
{
    freopen("fmcm.in","r",stdin);
    freopen("fmcm.out","w",stdout);
    int i,j,maxc,x,y,c,z,mini=INF,ok=0;

    scanf("%d%d%d%d",&n,&m,&s,&d);
    for(i=1;i<=m;++i)
    {
        scanf("%d%d%d%d",&x,&y,&c,&z);
        v[x].push_back(y);
        v[y].push_back(x);

        cost[x][y]=z;
        cost[y][x]=-z;

        f[y][x]=c;
    }
    for(i=1;i<=n;++i)
        for(j=1;j<=n;++j)
            if(cost[i][j]<mini)mini=cost[i][j];

    if(mini<0)
    {
        ok=1;
        mini=-mini;

        for(i=1;i<=n;++i)
            for(j=1;j<=n;++j)
                cost[i][j]+=mini;
    }

    while(drum())
    {
        maxc=INF;
        for(i=n;i!=s;i=t[i])
            if(f[i][t[i]]<maxc)
                maxc=f[i][t[i]];

        for(i=n;i!=s;i=t[i])
        {
            f[i][t[i]]-=maxc;
            f[t[i]][i]+=maxc;

            sol+=(cost[t[i]][i]-mini*ok) * maxc;
        }

        //sol+=maxc;
    }

    printf("%d\n",sol);

    return 0;
}