Cod sursa(job #2085387)

Utilizator FredyLup Lucia Fredy Data 10 decembrie 2017 01:25:20
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.71 kb
#include <bits/stdc++.h>

using namespace std;

ifstream fin("fmcm.in");
ofstream fout("fmcm.out");

#define lim 360
#define inf 2e9
int n,m,s,d,maxflow;
struct muchie {int x,y,cost,cap,flow;};
vector <muchie> e;
vector <int> G[lim];
int dist[lim],inq[lim],dad[lim],edad[lim],path[lim],dist2[lim];
queue <int> q;
priority_queue <pair <int, int>> pq;

void adauga (int x, int y, int cap, int cost)
{
    G[x].push_back(e.size());
    e.push_back({x,y,cost,cap,0});
    G[y].push_back(e.size());
    e.push_back({y,x,-cost,0,0});
}

void parcurgere_ini (int nod)
{
    q.push(nod);
    dist[nod]=0;
    for (int i=1; i<=n; i++)    dist[i]=inf;
    while (!q.empty())
    {
        int nod=q.front();
        q.pop();
        inq[nod]=0; /// daca nod e sau nu in coada
        for (auto it:G[nod])
            if (e[it].cap > e[it].flow  &&  dist[e[it].y] > dist[nod] + e[it].cost)
            {
                dist[e[it].y] = dist[nod] + e[it].cost;
                if (!inq[e[it].y])
                {
                    inq[e[it].y]=1;
                    q.push(e[it].y);
                }
            }
    }
}


bool dijkstra (int nod)
{
    while (!pq.empty()) pq.pop();
    for (int i=1; i<=n; i++)
        path[i]=dist2[i]=inf;
    path[nod]=dist2[nod]=0;
    pq.push({0,nod});

    while (!pq.empty())
    {
        nod = pq.top().second;
        if (path[nod] != -pq.top().first)
        {
            pq.pop();
            continue;
        }
        pq.pop();
        for (auto it:G[nod])
            if (e[it].cap > e[it].flow  &&  path[e[it].y] > path[nod] + e[it].cost + dist[e[it].x] - dist[e[it].y])
            {
                path[e[it].y] = path[nod] + e[it].cost + dist[e[it].x] - dist[e[it].y];
                dist2[e[it].y] = dist2[nod] + e[it].cost;
                dad[e[it].y] = nod;
                edad[e[it].y] = it;
                pq.push({-path[e[it].y], e[it].y});
            }
    }
    for (int i=1; i<=n; i++)
        dist[i] = dist2[i];
    return path[d]!=inf;
}
//bool dijkstra(int nod)
//{
//    while(PQ.size())
//    {
//        nod = PQ.top().second;
//        if(di[nod] != -PQ.top().first)
//        {
//            PQ.pop();
//            continue;
//        }
//        PQ.pop();
//        for(vector <int> :: iterator it = G[nod].begin() ; it != G[nod].end() ; it++)
//        {
//            if(e[*it].cap > e[*it].flow && di[e[*it].y] > di[nod] + e[*it].cost + dist[e[*it].x] - dist[e[*it].y])
//            {
//                di[e[*it].y] = di[nod] + e[*it].cost + dist[e[*it].x] - dist[e[*it].y];
//                dist2[e[*it].y] = dist2[nod] + e[*it].cost;
//                dad[e[*it].y] = nod;
//                edad[e[*it].y] = *it;
//                if(di[e[*it].y] - di[nod] < 0)
//                {
//                    cout << "!!!!!\n";
//                }
//               // if(e[*it].y == d)
//               //     return 1;
//                PQ.push(make_pair(-di[e[*it].y], e[*it].y));
//            }
//        }
//    }
//    for(int i = 1 ; i <= n ; i ++)
//    {
//        dist[i] = dist2[i];
//    }
//    return di[d] != inf;
//}

int main()
{
    int x,y,ca,cs;
    fin>>n>>m>>s>>d;
    while (m--)
    {
       fin>>x>>y>>ca>>cs;
       adauga (x,y,ca,cs);
    }

    parcurgere_ini(s);
    int minm,i;
    while (dijkstra(s))
    {
        minm=inf;
        for (i=d; dad[i]; i=dad[i])
            minm = min (minm, e[edad[i]].cap - e[edad[i]].flow);
        for (i=d; dad[i]; i=dad[i])
        {
            maxflow += (minm * e[edad[i]].cost);
            e[edad[i]].flow += minm;
            e[edad[i]^1].flow -= minm;
        }
    }
    fout<<maxflow;

    return 0;
}