Cod sursa(job #2792138)

Utilizator LicaMihaiIonutLica Mihai- Ionut LicaMihaiIonut Data 31 octombrie 2021 23:39:23
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.81 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <algorithm>
#include <cassert>
using namespace std;

const char iname[] = "cmcm.in";
const char oname[] = "cmcm.out";

const int MAX_N = 605;

vector < pair < pair <int, int>, int > > adj[MAX_N];

int capacity[MAX_N][MAX_N], flow_cost;

int getAugmentation(int n, int src, int dst) {
    const int inf = 0x3f3f3f3f;
    vector <int> d(n + 1, inf), p(n + 1, -1), inq(n + 1, 0);
    queue <int> q;
    vector < pair < pair <int, int>, int > >::iterator it;

    d[src] = 0, q.push(src), inq[src] = 1;
    while (!q.empty()) {
		int x = q.front();
		q.pop();
		for (it = adj[x].begin(); it != adj[x].end(); ++ it) {
			int y = it->first.first;
			int cost = it->first.second;
			if (capacity[x][y] > 0) if (d[x] < inf) if (d[y] > d[x] + cost) {
				d[y] = d[x] + cost;
				p[y] = x;
				if (!inq[y])
					q.push(y), inq[y] = 1;
			}
		}
		inq[x] = 0;
    }

    if (p[dst] != -1) {
        flow_cost += d[dst];
        for (int i = dst; i != src; i = p[i])
            capacity[p[i]][i] ^= 1, capacity[i][p[i]] ^= 1;
        return 1;
    }
    return 0;
}

int main(void) {
    ifstream in(iname);
    int cardL, cardR, cardEdges;

    assert(in >> cardL >> cardR >> cardEdges);
    assert(1 <= cardL && cardL <= 300);
    assert(1 <= cardR && cardR <= 300);
    assert(1 <= cardEdges && cardEdges <= 50000);
    int source = 0;
    int sink = cardL + cardR + 1;
    for (int i = 0; i < cardEdges; ++ i) {
        int x, y, cost;
        in >> x >> y >> cost;
        assert(-20000 <= cost && cost <= 20000);
        capacity[x][y + cardL] = 1;
        adj[x].push_back(make_pair(make_pair(y + cardL, cost), i));
        adj[y + cardL].push_back(make_pair(make_pair(x, -cost), -1));
    }
    for (int i = 1; i <= cardL; ++ i) {
        capacity[source][i] = 1;
		adj[source].push_back(make_pair(make_pair(i, 0), -1));
    }
    for (int j = 1; j <= cardR; ++ j) {
        capacity[j + cardL][sink] = 1;
        adj[j + cardL].push_back(make_pair(make_pair(sink, 0), -1));
    }

    while (getAugmentation(cardL + cardR + 2, source, sink)) ;

    vector <int> r_edges;
    int r_flow_cost = 0;
    for (int i = 1; i <= cardL; ++ i) {
        vector < pair < pair <int, int>, int > >::iterator it;
    	for (it = adj[i].begin(); it != adj[i].end(); ++ it) {
    		if (capacity[i][it->first.first] == 0)
    			r_edges.push_back(it->second),
    			r_flow_cost += it->first.second;
    	}
    }
    assert(flow_cost == r_flow_cost);

    ofstream out(oname);
    out << r_edges.size() << " " << r_flow_cost << "\n";
    sort(r_edges.begin(), r_edges.end());
    for (int i = 0; i < (int) r_edges.size(); ++ i)
        out << r_edges[i] + 1 << " ";
    in.close();
    out.close();
    return 0;
}