Cod sursa(job #2694823)

Utilizator ddeliaioanaaDumitrescu Delia Ioana ddeliaioanaa Data 10 ianuarie 2021 19:55:29
Problema Flux maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.02 kb
#include<bits/stdc++.h>
std::ifstream fin("fmcm.in");
std::ofstream fout("fmcm.out");

const int INF = 1e9;
int  n, m, s, d;
std::vector<int> nei[351];
int rGrph[351][351], parent[351], cost[351][351], dist[351];


void BellmanFord(){
    //calculam dist de la s la noduri
    int i, node;
    bool viz[351];
    std::queue<int> q;
    for(i = 1;i <= n; i++)
        dist[i] = INF;
    dist[s] = 0;
    q.push(s);
    viz[s] = 1;

    while(!q.empty()){
        node = q.front(); q.pop();
        viz[node] = 0;
        for(auto next_node: nei[node]){
            if(rGrph[node][node] && dist[next_node] > dist[node] + cost[node][next_node]){
                dist[next_node] = dist[node] + cost[node][next_node];
                if(!viz[next_node] && node != d){
                    q.push(next_node);
                    viz[next_node] = 1;
                }
            }
        }
    }
}

bool Dijkstra(){
    int aux_dist[351], new_dist[351];
    bool viz[351];
    std::priority_queue<std::pair<int, int>, std::vector<std::pair<int, int> >, std::greater<std::pair<int, int> > > q;
    int i, node, curr_cost, val;
    for(i = 1; i <= n; i++){
        aux_dist[i] = INF;
        new_dist[i] = 0;
        viz[i] = 0;
        parent[i] = 0;
    }

    aux_dist[s] = 0;
    parent[s] = -1;
    q.push({0,s});
    viz[s] = 1;

    while(!q.empty()){
        node = q.top().second;
        curr_cost = q.top().first;
        q.pop();

        if(node == d || aux_dist[node] != curr_cost)
            continue;

        viz[node] = 0;
        for(auto next_node: nei[node]){    // z + distx - disty
            val = cost[node][next_node] + dist[node] - dist[next_node];
            if(rGrph[node][next_node] && aux_dist[next_node] > curr_cost + val){
                aux_dist[next_node] = curr_cost + val;
                new_dist[next_node] = new_dist[node] + cost[node][next_node];
                parent[next_node] = node;
                q.push({aux_dist[next_node], next_node});
            }
        }
    }
    for(i = 1; i <= n; i++)
        dist[i] = new_dist[i];

    return (parent[d]); //am gasit sau nu drum
}

int mfmc(){
    int node, path_flow;
    int max_flow = 0;
    while(Dijkstra()){ //cat timp gasim drumuri actualizam
        path_flow = INF;
        node = d;
        while(parent[node] != -1){
            path_flow = std::min(path_flow, rGrph[parent[node]][node]);
            node = parent[node];
        }
        node = d;
        while(parent[node] != -1){
            rGrph[parent[node]][node] -= path_flow;
            rGrph[node][parent[node]] += path_flow;
            max_flow += path_flow * cost[parent[node]][node];
            node = parent[node];
        }
    }
    return max_flow;
}

void solve(){
    BellmanFord();
    fout << mfmc();
}

int main(){

    int i;
    fin >> n >> m >> s >> d;
    for(i = 0; i < m; i++){
        int x, y, c, z;
        fin >> x >> y >> c >> z;
        nei[x].push_back(y);
        nei[y].push_back(x);
        rGrph[x][y] = c;
        cost[x][y] = z;
        cost[y][x] = -z;
    }

    solve();

    return 0;
}