Cod sursa(job #3333105)

Utilizator rares89_Dumitriu Rares rares89_ Data 11 ianuarie 2026 05:06:32
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.08 kb
#include <fstream>
#include <vector>
#include <queue>
#include <algorithm>
#define INF 0x3f3f3f3f

using namespace std;

const int MAXN = 705; 

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

struct Edge {
    int to;
    int flow;
    int cap;
    int cost;
    int rev; // indicele muchiei inverse a lui 'to'
    int id; // indice original
};

vector<Edge> adj[MAXN];
int dist[MAXN];
int parent_node[MAXN];
int parent_edge_idx[MAXN];
bool inQueue[MAXN];

int N, M, E, S, D;

void add_edge(int u, int v, int cap, int cost, int id = -1) {
    Edge forward = {v, 0, cap, cost, (int)adj[v].size(), id};
    Edge backward = {u, 0, 0, -cost, (int)adj[u].size(), -1};
    adj[u].push_back(forward);
    adj[v].push_back(backward);
}

bool spfa() {
    for(int i = 0; i <= D; ++i) {
        dist[i] = INF;
        inQueue[i] = false;
        parent_node[i] = -1;
    }

    dist[S] = 0;
    queue<int> q;
    q.push(S);
    inQueue[S] = true;

    while(!q.empty()) {
        int u = q.front();
        q.pop();
        inQueue[u] = false;

        for(int i = 0; i < adj[u].size(); ++i) {
            Edge &e = adj[u][i];
            if(e.cap - e.flow > 0 && dist[e.to] > dist[u] + e.cost) {
                dist[e.to] = dist[u] + e.cost;
                parent_node[e.to] = u;
                parent_edge_idx[e.to] = i;
                
                if(!inQueue[e.to]) {
                    q.push(e.to);
                    inQueue[e.to] = true;
                }
            }
        }
    }

    return dist[D] != INF;
}

int main() {
    fin >> N >> M >> E;
    S = 0;
    D = N + M + 1;

    for(int i = 1; i <= E; ++i) {
        int u, v, cost;
        fin >> u >> v >> cost;
        add_edge(u, N + v, 1, cost, i);
    }
    fin.close();

    for(int i = 1; i <= N; ++i) {
        add_edge(S, i, 1, 0);
    }

    for(int i = 1; i <= M; ++i) {
        add_edge(N + i, D, 1, 0);
    }

    int max_flow = 0;
    int min_cost = 0;

    while(spfa()) {
        int flow = INF;
        int curr = D;
        
        while(curr != S) {
            int prev = parent_node[curr];
            int idx = parent_edge_idx[curr];
            flow = min(flow, adj[prev][idx].cap - adj[prev][idx].flow);
            curr = prev;
        }

        curr = D;
        while(curr != S) {
            int prev = parent_node[curr];
            int idx = parent_edge_idx[curr];
            
            adj[prev][idx].flow += flow;
            int rev_idx = adj[prev][idx].rev;
            adj[curr][rev_idx].flow -= flow;

            min_cost += flow * adj[prev][idx].cost;
            curr = prev;
        }
        
        max_flow += flow;
    }

    fout << max_flow << " " << min_cost << "\n";

    // L->R care au flux 1
    bool first = true;
    for(int u = 1; u <= N; ++u) {
        for(auto &e : adj[u]) {
            if(e.to > N && e.to <= N + M && e.flow == 1 && e.id != -1) {
                fout << e.id << " ";
                first = false;
            }
        }
    }
    fout << "\n";

    return 0;
}