Cod sursa(job #2698088)

Utilizator Alex_tz307Lorintz Alexandru Alex_tz307 Data 20 ianuarie 2021 22:21:10
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.92 kb
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f

using namespace std;

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

const int NMAX = 700;
const int source = 1;
int N, M, E;
vector<pair<int,int>> G[NMAX];
int sink, edge[NMAX][NMAX], capacity[NMAX][NMAX], flow[NMAX][NMAX];
int ans, cnt;

void read() {
    fin >> N >> M >> E;
    for(int i = 1; i <= E; ++i) {
        int u, v, w;
        fin >> u >> v >> w;
        ++u, v += N + 1;
        G[u].emplace_back(v, w);
        G[v].emplace_back(u, -w);
        edge[u][v] = i;
        capacity[u][v] = 1;
    }
}

void build() {
    sink = N + M + 2;
    for(int i = source + 1; i < N + 2; ++i) {
        G[1].emplace_back(i, 0);
        G[i].emplace_back(1, 0);
        capacity[1][i] = 1;
    }
    for(int i = N + 2; i < sink; ++i) {
        G[i].emplace_back(sink, 0);
        G[sink].emplace_back(i, 0);
        capacity[i][sink] = 1;
    }
}

void min_self(int &a, int b) {
    a = min(a, b);
}

int BellmanFord() {
    int dp[NMAX], father[NMAX];
    bool used[NMAX];
    memset(dp, 0x3f, sizeof(dp));
    memset(used, false, sizeof(used));
    fill(father, father + NMAX, -1);
    dp[source] = 0;
    used[source] = true;
    queue<int> Q;
    Q.emplace(source);
    while(!Q.empty()) {
        int curr = Q.front();
        Q.pop();
        used[curr] = false;
        for(const pair<int,int> &next : G[curr])
            if(capacity[curr][next.first] > flow[curr][next.first]
                && dp[next.first] > dp[curr] + next.second) {
                dp[next.first] = dp[curr] + next.second;
                father[next.first] = curr;
                if(!used[next.first]) {
                    Q.emplace(next.first);
                    used[next.first] = true;
                }
            }
    }
    if(dp[sink] < INF) {
        int flux = INF;
        for(int node = sink; node != source; node = father[node])
            min_self(flux, capacity[father[node]][node] - flow[father[node]][node]);
        for(int node = sink; node != source; node = father[node]) {
            flow[father[node]][node] += flux;
            flow[node][father[node]] -= flux;
        }
        return flux * dp[sink];
    }
    return 0;
}

void max_flow() {
    int improve = 1;
    while(improve != 0) {
        improve = BellmanFord();
        ans += improve;
    }
}

void print() {
    for(int i = source + 1; i < N + 2; ++i)
        for(int j = N + 2; j < sink; ++j)
            if(capacity[i][j] > 0 && flow[i][j] > 0) {
                ++cnt;
                break;
            }
    fout << cnt << ' ' << ans << '\n';
    for(int i = source + 1; i < N + 2; ++i)
        for(int j = N + 2; j < sink; ++j)
            if(capacity[i][j] > 0 && flow[i][j] > 0) {
                fout << edge[i][j] << ' ';
                break;
            }
}

int main() {
    read();
    build();
    max_flow();
    print();
}