Cod sursa(job #2124750)

Utilizator alexilasiAlex Ilasi alexilasi Data 7 februarie 2018 16:12:42
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.69 kb
#include <iostream>
#include <cstdio>
#include <vector>
#include <queue>
#include <string.h>
#define nmax 351
#define INF 1000000000
using namespace std;
queue <int> q;
vector <int> v[nmax];
vector <int>::iterator it;
priority_queue <pair<int,int> , vector<pair<int,int> > , greater <pair<int,int> > > h;
int c[nmax][nmax],t[nmax],distv[nmax],cost[nmax][nmax],dist[nmax],d,distr[nmax];
char viz[nmax];
void BFS(int i)
{
    int nod;
    q.push(i);
    while(!q.empty())
    {
        nod=q.front();
        q.pop();
        viz[nod]=0;
        for(it=v[nod].begin();it!=v[nod].end();it++)
        {
            if(c[nod][*it]>0 && distv[*it]>distv[nod]+cost[nod][*it])
            {
                distv[*it]=distv[nod]+cost[nod][*it];
                if(viz[*it]==0)
                {
                    viz[*it]=1;
                    q.push(*it);
                }

            }
        }
    }
}
void dijkstra(int i)
{
    int noudist,nod,cst;
    h.push(make_pair(0,i));
    while(!h.empty())
    {
        nod=h.top().second;
        cst=h.top().first;
        h.pop();
        if(dist[nod]==cst)
            for(it=v[nod].begin();it!=v[nod].end();it++)
                if(c[nod][*it])
                {
                    noudist=dist[nod]+cost[nod][*it]+distv[nod]-distv[*it];//noua distanta
                    if(dist[*it]>noudist )
                    {
                        t[*it]=nod;
                        dist[*it]=noudist;
                        distr[*it]=distr[nod]+cost[nod][*it];
                        h.push(make_pair(dist[*it],*it));
                    }
                }

    }
}
int main()
{
    int rez=0,m,i,x,y,flux,s,n;
    freopen("fmcm.in", "rt", stdin);
    freopen("fmcm.out", "wt", stdout);
    scanf("%d %d %d %d",&n, &m, &s, &d);
    for(i=1;i<=m;i++)
    {
        scanf("%d %d", &x,&y);
        scanf("%d %d", &c[x][y], &cost[x][y]);
        cost[y][x]=-cost[x][y];
        v[x].push_back(y);
        v[y].push_back(x);
    }
    for(i=1;i<=n;i++)
        distv[i]=INF;
    distv[s]=0;
    BFS(s);
    while(1)
    {
        memset(t,0,sizeof(t));
        for(i=1;i<=n;i++)
            dist[i]=INF;
        dist[s]=0;
        distr[s]=0;
        dijkstra(s);
        if(t[d]==0)
            break;
        for(i=1;i<=n;i++)
            distv[i]=distr[i];
        flux=INF;
        x=d;
        while(x!=s)
        {
            flux=min(flux,c[t[x]][x]);
            x=t[x];
        }
        x=d;
        rez+=flux*distr[d];
        while(x!=s)
        {
            c[t[x]][x]-=flux;
            c[x][t[x]]+=flux;
            x=t[x];
        }
    }
    cout<<rez<<'\n';
    return 0;
}