Cod sursa(job #2720252)

Utilizator georgerapeanuRapeanu George georgerapeanu Data 10 martie 2021 18:04:26
Problema Flux maxim de cost minim Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.17 kb
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>

using namespace std;

const int NMAX = 350;
const int MMAX = 12500;
const int inf = 1e9;

struct edge_t{
    int from;
    int to;
    int cap;
    int cst;
    int flow;
};

edge_t edges[2 * MMAX + 5];

int n,m,s,d;
int father[NMAX + 5];
int real_dist[NMAX + 5];
int dist[NMAX + 5];
int old_dist[NMAX + 5];
vector<int> graph[NMAX + 5];


queue<int> q;
bool inq[NMAX + 5];
bool bellman(int s,int d){

    for(int i = 1;i <= n;i++){
        inq[i] = false;
        real_dist[i] = inf;
    }

    inq[s] = true;
    real_dist[s] = 0;
    q.push(s);

    while(!q.empty()){
        int nod = q.front();
        q.pop();
        inq[nod] = false;

        if(nod == d){
            continue;
        }

        for(auto it:graph[nod]){
            if(edges[it].flow < edges[it].cap && real_dist[edges[it].to] > real_dist[nod] + edges[it].cst){
                real_dist[edges[it].to] = real_dist[nod] + edges[it].cst;
                if(inq[edges[it].to] == false){
                    inq[edges[it].to] = true;
                    q.push(edges[it].to);
                }
            }
        }
    }
    
    return real_dist[d] != inf; 
}

priority_queue<pair<int,int>,vector<pair<int,int> > ,greater<pair<int,int> > > pq;
bool dijkstra(int s,int d){
    for(int i = 1;i <= n;i++){
        old_dist[i] = real_dist[i];
        dist[i] = inf;
        real_dist[i] = inf;
        father[i] = 0;
    }

    dist[s] = 0;
    real_dist[s] = 0;
    pq.push({0,s});

    while(pq.empty() == false){
        pair<int,int> tmp = pq.top();
        pq.pop();

        if(dist[tmp.second] != tmp.first){
            continue;
        }

        if(tmp.second == d){
            break;
        }

        for(auto it:graph[tmp.second]){
            if(edges[it].flow < edges[it].cap && dist[edges[it].to] > tmp.first + old_dist[edges[it].from] + edges[it].cst - old_dist[edges[it].to]){
                dist[edges[it].to] = tmp.first + old_dist[edges[it].from] + edges[it].cst - old_dist[edges[it].to];
                real_dist[edges[it].to] = real_dist[tmp.second] + edges[it].cst;
                father[edges[it].to] = it;
                pq.push({dist[edges[it].to],edges[it].to});
            }
        }
    }

    return dist[d] != inf;
}

long long fmcm(int s,int d){
    long long ans = 0;

    for(bellman(s,d);dijkstra(s,d);){
        int fmin = inf;
        for(int nod = d;nod != s;nod = edges[father[nod]].from){
            fmin = min(fmin,edges[father[nod]].cap - edges[father[nod]].flow);
        }
        ans += fmin * real_dist[d];
        for(int nod = d;nod != s;nod = edges[father[nod]].from){
            edges[father[nod]].flow += fmin;
            edges[father[nod] ^ 1].flow -= fmin;
        }
    }

    return ans;
}

int main(){
   
    freopen("fmcm.in","r",stdin);
    freopen("fmcm.out","w",stdout);

    scanf("%d %d %d %d",&n,&m,&s,&d);

    for(int i = 0;i < m;i++){
        int x,y,c,z;
        scanf("%d %d %d %d",&x,&y,&c,&z);
      
        edges[2 * i] = {x,y,c,z,0};
        edges[2 * i + 1] = {y,x,0,-z,0};

        graph[x].push_back(2 * i);
        graph[y].push_back(2 * i + 1);
    }

    printf("%lld\n",fmcm(s,d));

    return 0;
}