Cod sursa(job #2040247)

Utilizator zhm248Mustatea Radu zhm248 Data 15 octombrie 2017 15:47:52
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.55 kb
#include<cstdio>
#include<queue>
#include<cstring>
#include<vector>
using namespace std;
typedef pair<int,int>ii;
priority_queue<ii,vector<ii>,greater<ii> >pq;
queue<int>q;
vector<int>g[351];
int cap[351][351],cos[351][351],vd[351],dd[351],nd[351],pi[351];
bool inq[351];
int main()
{
    freopen("fmcm.in","r",stdin);
    freopen("fmcm.out","w",stdout);
    int n,m,s,d,i,x,y,c,z,cost=0,minim;
    scanf("%d%d%d%d",&n,&m,&s,&d);
    for(i=1; i<=m; ++i)
    {
        scanf("%d%d%d%d",&x,&y,&c,&z);
        cap[x][y]+=c;
        cos[x][y]+=z;
        cos[y][x]-=z;
        g[x].push_back(y);
        g[y].push_back(x);
    }
    memset(vd,0x3f,sizeof(vd));
    vd[s]=0;
    q.push(s);
    while(!q.empty())
    {
        int t=q.front();
        q.pop();
        for(i=0; i<g[t].size(); ++i)
        {
            int v=g[t][i];
            if(cap[t][v])
            {
                if(vd[t]+cos[t][v]<vd[v])
                {
                    vd[v]=vd[t]+cos[t][v];
                    if(!inq[v])
                    {
                        inq[v]=1;
                        q.push(v);
                    }
                }
            }
        }
    }
    while(true)
    {
        memset(dd,0x3f,sizeof(dd));
        dd[s]=nd[s]=0;
        pq.push(ii(0,s));
        while(!pq.empty())
        {
            int x1=pq.top().first;
            int x2=pq.top().second;
            pq.pop();
            if(dd[x2]==x1)
            {
                for(i=0; i<g[x2].size(); ++i)
                {
                    int v=g[x2][i];
                    if(cap[x2][v])
                    {
                        int val=dd[x2]+cos[x2][v]+vd[x2]-vd[v];
                        if(val<dd[v])
                        {
                            dd[v]=val;
                            nd[v]=nd[x2]+cos[x2][v];
                            pi[v]=x2;
                            pq.push(ii(dd[v],v));
                        }
                    }
                }
            }
        }
        memcpy(vd,nd,sizeof(dd));
        if(dd[d]==0x3f3f3f3f)
            break;
        minim=0x3f3f3f3f;
        int val=d;
        while(val!=s)
        {
            if(minim>cap[pi[val]][val])
                minim=cap[pi[val]][val];
            val=pi[val];
        }
        cost+=minim*nd[d];
        val=d;
        while(val!=s)
        {
            cap[pi[val]][val]-=minim;
            cap[val][pi[val]]+=minim;
            val=pi[val];
        }
    }
    printf("%d\n",cost);
    return 0;
}