Cod sursa(job #2462417)

Utilizator mihai50000Mihai-Cristian Popescu mihai50000 Data 27 septembrie 2019 11:53:09
Problema Cuplaj maxim de cost minim Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.75 kb
#include <bits/stdc++.h>

using namespace std;

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

const int DIM = 357 * 3;
const int INF = 1e9;

int n, m, s, d;

vector <pair <int, int> > v[DIM];

int cost[DIM][DIM];
int flux[DIM][DIM];
int cap[DIM][DIM];
int father[DIM];
int dist[DIM];

bool bellman()
{
    queue <int> q;

    for(int i = 1; i <= n; i++)
        dist[i] = INF;

    dist[s] = 0;

    q.push(s);

    bitset <DIM> vis;

    vis[s] = true;

    while(!q.empty())
    {
        int nod = q.front();
        q.pop();

        vis[nod] = false;

        for(int i = 0; i < v[nod].size(); i++)
            if(cap[nod][v[nod][i].first] != 0)
            {
                if(dist[v[nod][i].first] > dist[nod] + cost[nod][v[nod][i].first])
                {
                    father[v[nod][i].first] = nod;
                    dist[v[nod][i].first] = dist[nod] + cost[nod][v[nod][i].first];

                    if(v[nod][i].first != d && vis[v[nod][i].first] == false)
                    {
                        vis[v[nod][i].first] = true;
                        q.push(v[nod][i].first);
                    }
                }
            }
    }

    if(dist[d] == INF)
        return false;

    return true;
}

vector <int> sol;

main()
{
    int n2;
    fin >> n >> n2 >> m;

    for(int i = 1; i <= m; i++)
    {
        int x, y, z;
        fin >> x >> y >> z;

        y += n;

        cap[x][y] = 1;
        cost[x][y] = z;
        cost[y][x] = -z;

        v[x].push_back({y, i});
        v[y].push_back({x, i});
    }

    s = n + n2 + 1;
    d = n + n2 + 2;

    for(int i = 1; i <= n; i++)
    {
        v[s].push_back({i, 0});
        v[i].push_back({s, 0});

        cap[s][i] = 1;
    }

    for(int i = n + 1; i <= n + n2; i++)
    {
        v[d].push_back({i, 0});
        v[i].push_back({d, 0});

        cap[i][d] = 1;
    }

    n += n2;
    n += 2;

    int sum = 0;

    while(bellman())
    {
        int flux = INF;

        for(int i = d; i != s; i = father[i])
            flux = min(flux, cap[father[i]][i]);

        for(int i = d; i != s; i = father[i])
        {
            cap[father[i]][i] -= flux;
            cap[i][father[i]] += flux;

            sum += flux * cost[father[i]][i];
        }
    }

    n -= 2;
    n -= n2;

    int nr = 0;

    for(int i = 1; i <= n; i++)
        for(int j = 0; j < v[i].size(); j++)
            if(v[i][j].first < n + n2 && cap[i][v[i][j].first] == 0)
            {
                    nr++;
                    sol.push_back(v[i][j].second);
            }

    fout << nr << ' ' << sum << '\n';

    for(int i = 0; i < sol.size(); i++)
        fout << sol[i] << ' ';
}