Cod sursa(job #1601205)

Utilizator DrumeaVDrumea Vasile DrumeaV Data 15 februarie 2016 20:11:04
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.67 kb
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>

using namespace std;

const int Mn = 703;
const int oo = 1 << 30;

int n, m, e, dest, sol, cst;
int parent[Mn], dst[Mn];
int cap[Mn][Mn], flow[Mn][Mn], id[Mn][Mn];
bool used[Mn];
vector< int > g[Mn], cost[Mn], ans;
queue< int > q;

int bellmanford()
{
    memset(used, 0, sizeof(used));
    for (int i = 2; i <= dest; i++)
        dst[i] = oo;

    used[1] = 1;
    dst[1] = 0;
    q.push(1);

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

        for (int i = 0; i < g[x].size(); i++)
            if (cap[x][g[x][i]] > flow[x][g[x][i]] && dst[g[x][i]] > dst[x] + cost[x][i])
            {
                dst[g[x][i]] = dst[x] + cost[x][i];
                parent[g[x][i]] = x;

                if (!used[g[x][i]])
                {
                    q.push(g[x][i]);
                    used[g[x][i]] = 1;
                }
            }
    }

    if (dst[dest] == oo)
       return 0;

    int mn = oo;
    for (int node = dest; node != 1; node = parent[node])
        mn = min(mn, cap[parent[node]][node] - flow[parent[node]][node]);

    for (int node = dest; node != 1; node = parent[node])
    {
        flow[parent[node]][node] += mn;
        flow[node][parent[node]] -= mn;
    }

    return mn * dst[dest];
}

int main()
{
    freopen("cmcm.in", "r", stdin);
    freopen("cmcm.out", "w", stdout);

    scanf("%d %d %d", &n, &m, &e);
    for (int i = 1; i <= e; i++)
    {
        int a, b, c;
        scanf("%d %d %d", &a, &b, &c);

        a++; b += n + 1;
        g[a].push_back(b); g[b].push_back(a);
        cost[a].push_back(c); cost[b].push_back(-c);
        cap[a][b] = 1;
        id[a][b] = i;
    }

    dest = n + m + 2;
    for (int i = 2; i <= n + 1; i++)
    {
        g[1].push_back(i); g[i].push_back(1);
        cost[1].push_back(0); cost[i].push_back(0);
        cap[1][i] = 1;
    }

    for (int i = n + 2; i <= n + m + 1; i++)
    {
        g[i].push_back(dest); g[dest].push_back(i);
        cost[i].push_back(0); cost[dest].push_back(0);
        cap[i][dest] = 1;
    }

    int aux;

    do
    {
        aux = bellmanford();
        cst += aux;

    }while (aux);

    for (int i = 2; i <= n + 1; i++)
        for (int j = n + 2; j < dest; j++)
            if (cap[i][j] && flow[i][j])
            {
                sol++;
                ans.push_back(id[i][j]);
                break;
            }

    printf("%d %d\n", sol, cst);
    for (int i = 0;i < sol; printf("%d ",ans[i]), i++);

    printf("\n");

  return 0;
}