Cod sursa(job #3251354)

Utilizator not_anduAndu Scheusan not_andu Data 25 octombrie 2024 19:56:54
Problema Cuplaj maxim de cost minim Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.61 kb
#include <bits/stdc++.h>

using namespace std;

#define INFILE "cmcm.in"
#define OUTFILE "cmcm.out"

const int N_MAX = 2 * 300;
const int INF = 1e9;

struct Node {

public:
    int node;
    int cost;

    Node(){}
    Node(int _node, int _cost) : node(_node), cost(_cost) {}

    bool operator<(const Node &other) const {
        return (this -> cost > other.cost);
    }

};

int stanga, dreapta, m, destinatie;
int cost;
int dist[N_MAX + 5];
int parent[N_MAX + 5];
vector<Node> adj[N_MAX + 5];
unordered_set<int> visitedEdges;
int indice[N_MAX + 5][N_MAX + 5];
bool capacity[N_MAX + 5][N_MAX + 5];

bool dijkstra(){

    memset(dist, 0x3f3f3f3f, sizeof dist);
    dist[1] = 0;

    priority_queue<Node> q; q.push(Node(1, 0));

    while(!q.empty()){
        
        int node = q.top().node;
        int cost = q.top().cost;
        q.pop();

        if(cost != dist[node]) continue;

        for(auto &to : adj[node]){
            if(capacity[node][to.node] && dist[node] + to.cost < dist[to.node]){
                dist[to.node] = dist[node] + to.cost;
                parent[to.node] = node;
                q.push(Node(to.node, dist[to.node]));
            }
        }

    }

    return (dist[destinatie] < INF);

}

void solve(){

    cin >> stanga >> dreapta >> m;
    destinatie = stanga + dreapta + 2;
    for(int i = 1; i <= m; ++i){
        int node, to, cost; cin >> node >> to >> cost;
        ++node;
        to += stanga + 1;
        adj[node].push_back(Node(to, cost));
        adj[to].push_back(Node(node, -cost));
        indice[node][to] = i;
        indice[to][node] = -i;
        capacity[node][to] = true;
    }

    for(int i = 2; i <= stanga + 1; ++i){
        adj[1].push_back(Node(i, 0));
        adj[i].push_back(Node(1, 0));
        capacity[1][i] = true;
    }
    for(int i = stanga + 2; i < destinatie; ++i){
        adj[i].push_back(Node(destinatie, 0));
        adj[destinatie].push_back(Node(i, 0));
        capacity[i][destinatie] = true;
    }

    while(dijkstra()){

        for(int i = destinatie; i != 1; i = parent[i]){
            capacity[parent[i]][i] = false;
            capacity[i][parent[i]] = true;
            int aux = indice[parent[i]][i];
            if(aux > 0) visitedEdges.insert(aux);
            else visitedEdges.erase(aux);
        }
        
        cost += dist[destinatie];

    }

    cout << visitedEdges.size() << " " << cost << '\n';
    for(auto &it : visitedEdges){
        cout << it << " ";
    }
    cout << '\n';

}

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    freopen(INFILE, "r", stdin);
    freopen(OUTFILE, "w", stdout);
    solve();
    return 0;
}