Cod sursa(job #2458939)

Utilizator bluestorm57Vasile T bluestorm57 Data 21 septembrie 2019 22:00:50
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.56 kb
#include <bits/stdc++.h>

using namespace std;

ifstream f("cmcm.in");
ofstream g("cmcm.out");

const int NMAX = 800;
const int inf = (1 << 30);
int n,m,e;
vector <pair <int, int > > v[NMAX];
int edge[NMAX][NMAX], dest, dist[NMAX],ans,c[NMAX][NMAX];
int father[NMAX], used[NMAX], Q[NMAX], F[NMAX][NMAX];

int bellman(){
    int i;
    for(i = 1 ; i <= dest ; i++){
        dist[i] = inf;
        father[i] = -1;
        used[i] = 0;
    }
    dist[1] = 0;
    used[1] = 1;
    deque <int> q;
    q.push_back(1);
    int node,it;
    while(!q.empty()){
        node = q.front();
        q.pop_front();
        for(auto it: v[node]){
            if(c[node][it.first] > F[node][it.first] && dist[it.first] > dist[node] + it.second){
                dist[it.first] = dist[node] + it.second;
                father[it.first] = node;
                if(!used[it.first]){
                    q.push_back(it.first);
                    used[it.first] = 1;
                }
            }
        }
        used[node] = 0;
    }

    if(dist[dest] < inf){

        int flux = inf;

        for(i = dest ; i != 1 ; i = father[i])
            flux = min(flux, c[father[i]][i] - F[father[i]][i]);

        for(i = dest ; i != 1 ; i = father[i]){
            F[father[i]][i] += flux;
            F[i][father[i]] -= flux;
        }
        return flux * dist[dest];

    }
    return 0;
}

int main(){
    int i,x,y,val,j;
    f >> n >> m >> e;
    for(i = 1 ; i <= e ; i++){
        f >> x >> y >> val;
        y += n + 1;
        x++;
        v[x].push_back(make_pair(y,val));
        v[y].push_back(make_pair(x,-val));
        edge[x][y] = i;
        c[x][y] = 1;
    }

    dest = n + m + 2;
    for(i = 2 ; i <= n + 1 ; i++){
        v[1].push_back(make_pair(i,0));
        v[i].push_back(make_pair(1,0));
        c[1][i] = 1;
    }
    for(i = n + 2 ; i <= n + m + 1 ; i++){
        v[i].push_back(make_pair(dest,0));
        v[dest].push_back(make_pair(i,0));
        c[i][dest] = 1;
    }

    int improve = 1;
    while(improve){
        improve = bellman();
        ans += improve;
    }

    int nr = 0;
    for(i = 2 ; i <= n + 1 ; i++)
        for(j = n + 2 ; j < dest ; j++)
            if(c[i][j] && F[i][j]){
                nr++;
                break;
            }

    g << nr << " " << ans << "\n";
    for(i = 2 ; i <= n + 1 ; i++)
        for(j = n + 2 ; j < dest ; j++)
            if(c[i][j] && F[i][j]){
                g << edge[i][j] << " ";
                break;
            }

    return 0;
}