Cod sursa(job #2117791)

Utilizator LucaSeriSeritan Luca LucaSeri Data 29 ianuarie 2018 18:30:37
Problema Cuplaj maxim de cost minim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.68 kb
#include <bits/stdc++.h>

using namespace std;

const int MAXN = 700;
const int INF = 0x3f3f3f3f;

struct edges{
    int from, to, cost, cnt;
    edges(int _from = 0, int _to = 0, int _cost = 0, int _cnt = 0){
        from = _from;
        to = _to;
        cost = _cost;
        cnt = _cnt;
    }
};
vector< edges > gr[MAXN];
int current_flow[MAXN][MAXN];
int capacity[MAXN][MAXN];
edges boss[MAXN];
int dist[MAXN];
bool in_queue[MAXN];
int cnt[50010];

ifstream f("cmcm.in");
ofstream g("cmcm.out");


bool bellman_ford(int source, int target){
    bool verif = false;
    queue< int > Q;

    memset(dist, 0x3f, sizeof dist);
    dist[source] = 0;
    Q.push(source);
    while(Q.size()){
        int node = Q.front();
        Q.pop();
        in_queue[node] ^= 1;
        if(node == target) verif = true;
        for(auto x : gr[node]){
            int next = x.to;
            if(dist[node] + x.cost < dist[next] && current_flow[node][next] < capacity[node][next]){
                dist[next] = dist[node] + x.cost;
                boss[next] = x;
                if(in_queue[next]) continue;
                in_queue[next] ^= 1;
                Q.push(next);
            }
        }
    }

    return verif;
}

vector< int > sol;

int main(){
    int n, m, e;
    f >> n >> m >> e;
    int source = 0;
    int target = n + m + 1;
    for(int i = 1; i <= e; ++i){
        int a, b, c;
        f >> a >> b >> c;
        b += n;
        edges edge(a, b, c, i);
        edges edge2(b, a, -c, i);
        gr[source].push_back({source, a, 0, 0});
        gr[a].push_back({a, source, 0, 0});
        gr[a].push_back(edge);
        gr[b].push_back(edge2);
        gr[target].push_back({target, b, 0, 0});
        gr[b].push_back({b, target, 0, 0});

        capacity[source][a] = 1;
        capacity[a][b] = 1;
        capacity[b][target] = 1;
    }
    int ans = 0;
    int cost = 0;
    while(bellman_ford(source, target)){
        int node = target;
        int minimum_flow = (1<<30);
        while(node != source){
            minimum_flow = min(minimum_flow, capacity[boss[node].from][node] - current_flow[boss[node].from][node]);
            cnt[boss[node].cnt] ^= 1;
            node = boss[node].from;
        }
        node = target;
        while(node != source){
            current_flow[boss[node].from][node] += minimum_flow;
            current_flow[node][boss[node].from] -= minimum_flow;
            node = boss[node].from;
        }

        ans += minimum_flow;
        cost += minimum_flow * dist[target];
    }

    g << ans << ' ' << cost << '\n';

    for(int i = 1; i <= e; ++i) if(cnt[i]) g << i << ' ';
    return 0;
}