Cod sursa(job #2807493)

Utilizator As932Stanciu Andreea As932 Data 23 noiembrie 2021 20:57:44
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.13 kb
#include <bits/stdc++.h>
#define per pair<int,int>
#define inf 0x3f3f3f3f

using namespace std;

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

const int nmax = 6e2 + 5;

int n, m, e;
int tt[nmax], dr[nmax];
int cost[nmax][nmax], cap[nmax][nmax], f[nmax][nmax];
bitset <nmax> vis;
vector <per> edg[nmax];
queue <int> q;

void read(){
    fin >> n >> m >> e;
    for(int i = 1; i <= e; i++){
        int p, q, c;
        fin >> p >> q >> c;
        edg[p].push_back({n + q, i});
        edg[n + q].push_back({p, 0});
        cap[p][n + q] = 1;
        cost[p][n + q] = c;
        cost[n + q][p] = -c;
    }
}

void build_graph(){
    for(int i = 1; i <= n; i++){
        cap[0][i] = 1;
        edg[0].push_back({i, 0});
        edg[i].push_back({0, 0});
    }
    for(int i = n + 1; i <= n + m; i++){
        cap[i][n + m + 1] = 1;
        edg[i].push_back({n + m + 1, 0});
        edg[n + m + 1].push_back({i, 0});
    }
}

bool bfs(){
    vis.reset();
    memset(dr, inf, sizeof(dr));
    memset(tt, 0, sizeof(tt));

    vis[0] = 1;
    dr[0] = 0;
    q.push(0);

    while(!q.empty()){
        int x = q.front();
        q.pop();
        vis[x] = 0;

        for(auto y:edg[x])
            if(cap[x][y.first] > f[x][y.first] && dr[y.first] > dr[x] + cost[x][y.first]){
                dr[y.first] = dr[x] + cost[x][y.first];
                tt[y.first] = x;
                if(!vis[y.first]){
                    vis[y.first] = 1;
                    q.push(y.first);
                }
            }
    }

    return (dr[n + m + 1] != inf);
}

void solve(){
    int cnt = 0, costMin = 0;

    while(bfs()){
        for(int i = n + m + 1; i != 0; i = tt[i]){
            f[tt[i]][i]++;
            f[i][tt[i]]--;
        }
        cnt++;
        costMin += dr[n + m + 1];
    }

    fout << cnt << " " << costMin << "\n";
    for(int i = 1; i <= n; i++)
        for(auto j:edg[i])
            if(f[i][j.first] == 1){
                fout << j.second << " ";
                break;
            }
}

int main()
{
    read();
    build_graph();
    solve();

    return 0;
}