Cod sursa(job #1404822)

Utilizator radarobertRada Robert Gabriel radarobert Data 28 martie 2015 16:21:53
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.91 kb
#include <fstream>
#include <vector>
#include <cstring>
#include <queue>
#include <iostream>

using namespace std;

const int INF = 0x3f3f3f3f;

vector<int> g[602];
int n, m;
int cap[604][604];
int flow[604][604];
int cost[604][604];
int id[604][604];
int d[604];
int last[604];
bool in_queue[604];
bool used_edge[50004];

bool BellmanFord()
{
    memset(d, INF, sizeof(d));
    memset(in_queue, false, sizeof(in_queue));
    memset(last, 0, sizeof(last));

    queue<int> q;
    q.push(0);
    d[0] = 0;
    in_queue[0] = true;
    int x;
    while (!q.empty())
    {
        x = q.front();
        in_queue[x] = false;
        q.pop();
        for (int i = 0; i < g[x].size(); i++)
            if (flow[x][g[x][i]] < cap[x][g[x][i]])
                if (d[g[x][i]] > d[x] + cost[x][g[x][i]])
                {
                    last[g[x][i]] = x;
                    d[g[x][i]] = d[x] + cost[x][g[x][i]];
                    if (!in_queue[g[x][i]])
                    {
                        q.push(g[x][i]);
                        in_queue[g[x][i]] = true;
                    }
                }
    }
    if (d[n+m+1] == INF)
        return false;
    return true;
}

int main()
{
    ifstream in("cmcm.in");
    ofstream out("cmcm.out");

    int e;
    in >> n >> m >> e;
    for (int x, y, z, i = 1; i <= e; i++)
    {
        in >> x >> y >> z;
        y += n;
        id[x][y] = i;
        id[y][x] = i;
        cap[x][y] = 1;
        g[x].push_back(y);
        g[y].push_back(x);
        cost[x][y] = z;
        cost[y][x] = -z;
    }
    for (int i = 1; i <= n; i++)
    {
        cost[0][i] = 0;
        g[0].push_back(i);
        g[i].push_back(0);
        cap[0][i] = 1;
    }
    for (int j = 1; j <= m; j++)
    {
        cost[j+n][n+m+1] = 0;
        g[j+n].push_back(n+m+1);
        g[n+m+1].push_back(j+n);
        cap[j+n][n+m+1] = 1;
    }

    int costmin = 0;
    int cm = 0;
    while (BellmanFord())
    {
        int fmax = 0;
        for (int k = n+m+1; k != 0; k = last[k])
        {
            cerr << k << '\n';
            if (cap[last[k]][k] - flow[last[k]][k] > fmax)
                fmax = cap[last[k]][k] - flow[last[k]][k];
        }
        cm += fmax;
        for (int k = n+m+1; k != 0; k = last[k])
        {
            flow[last[k]][k] += fmax;
            if (cap[last[k]][k] == 1)
            {
                costmin += cost[last[k]][k];
                used_edge[id[last[k]][k]] = 1;
                //out << last[k] << ' ' << k << ' ' << cost[last[k]][k] << '\n';
            }
            else
            {
                costmin += cost[last[k]][k];
                used_edge[id[last[k]][k]] = 0;
                //out << last[k] << ' ' << k << ' ' << -1 * cost[last[k]][k] << '\n';
            }
            flow[k][last[k]] -= fmax;
        }
    }

    out << cm << ' ' << costmin << '\n';
    for (int i = 1; i <= e; i++)
        if (used_edge[i])
            out << i << ' ';
    out << '\n';

    return 0;
}