Cod sursa(job #2694279)

Utilizator buhaidarius@gmail.comBuhai Darius [email protected] Data 8 ianuarie 2021 17:35:18
Problema Cuplaj maxim de cost minim Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.65 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>

#define pii pair<int,int>
#define N 601
#define INF 1e9
#define LL long long

using namespace std;

int n1, n2, n, k, s, t;
vector<vector<int>> v;
int residual[N][N], arches[N][N], cost[N][N], dist2[N], visited[N], false_dist[N], dist[N], path[N];

void bellman_ford(){
    queue<int> q;
    dist[s] = 0;
    q.emplace(s);
    visited[s] = true;
    while(!q.empty()){
        int current = q.front();
        q.pop();
        visited[current] = false;
        for(auto &node: v[current])
            if(residual[current][current] && dist[node]>dist[current]+cost[current][node]){
                dist[node] = dist[current]+cost[current][node];
                if(!visited[node] && current!=t){
                    q.emplace(node);
                    visited[node] = true;
                }
            }
    }
}

bool dijkstra(){
    priority_queue<pii, vector<pii>, greater<>> pq;
    for(int i=1;i<=n;++i){
        visited[i] = false;
        path[i] = 0;
        false_dist[i] = INF;
    }
    false_dist[s] = 0;
    path[s] = -1;
    pq.emplace(0, s);
    visited[s] = true;
    while(!pq.empty()){
        int current = pq.top().second;
        int current_cost = pq.top().first;
        pq.pop();
        if(current==t || false_dist[current]!=current_cost) continue;
        visited[current] = false;
        for(auto &node: v[current])
            if(residual[current][node] && false_dist[node]>current_cost+cost[current][node]+dist[current]-dist[node]){
                false_dist[node] = current_cost + cost[current][node] + dist[current] - dist[node];
                dist2[node] = dist2[current] + cost[current][node];
                path[node] = current;
                pq.emplace(false_dist[node], node);
            }
    }
    for(int i=1;i<=n;i++)
        dist[i] = dist2[i];
    return path[t];
}

LL ford_fulkerson(){
    LL max_flow = 0;
    while(dijkstra()){
        int current = t, flow = INF;
        while(path[current]!=-1){
            flow = min(flow, residual[path[current]][current]);
            current = path[current];
        }
        current = t;
        while(path[current]!=-1){
            residual[path[current]][current] -= flow;
            residual[current][path[current]] += flow;
            current = path[current];
            max_flow+=flow * cost[path[current]][current];
        }
    }
    return max_flow;
}

int main() {
    ifstream fin("cmcm.in");
    ofstream fout("cmcm.out");
    fin>>n1>>n2>>k;
    n = n1+n2+2;
    v.resize(n+1);
    for(int i=1;i<=k;++i){
        int a, b, c;
        fin>>a>>b>>c;
        b+=n1;
        v[a].emplace_back(b);
        v[b].emplace_back(a);
        residual[a][b] = 1;
        arches[a][b] = i;
        cost[a][b] = c;
        cost[b][a] = -c;
    }
    /// set start and end
    s = n-1;
    t = n;
    /// pair s with left side
    for(int i=1;i<=n1;++i){
        v[s].emplace_back(i);
        v[i].emplace_back(s);
        residual[s][i] = 1;
        cost[s][i] = cost[i][s] = 0;
    }
    /// pair t with right side
    for(int i=n1+1;i<=n1+n2;++i){
        v[t].emplace_back(i);
        v[i].emplace_back(t);
        residual[i][t] = 1;
        cost[t][i] = cost[i][t] = 0;
    }
    /// apply bellman ford to make all costs positive
    bellman_ford();
    /// run ford fulkerson algorithm with dijkstra
    LL max_flow = ford_fulkerson();
    /// print results
    vector<int> ans;
    for(int i=1;i<=n1;++i)
        for(auto &node: v[i])
            if(!residual[i][node] && residual[node][i] && node!=s)
                ans.emplace_back(arches[i][node]);
    fout<<ans.size()<<' '<<max_flow<<'\n';
    for(auto i: ans)
        fout<<i<<' ';
    return 0;
}