Cod sursa(job #1784399)

Utilizator bogdan10bosBogdan Sitaru bogdan10bos Data 19 octombrie 2016 23:41:43
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.65 kb
#include <bits/stdc++.h>

using namespace std;

#define FILE_IO

typedef pair<int, int> pii;
typedef pair<int, pii> p3i;

int N, M, K, E, S, T;
int cp[1005][1005];
int cst[1005][1005];
int mch[1005][1005];
int used[50005];
int f[1005], d[1005], inq[1005];
int flow, cost;

queue <int> q;
vector <int> edg[1005];

void BFS()
{
    for(int i = 1; i <= K; i++)
        d[i] = 1 << 30;
    memset(f, 0, sizeof(f));
    f[S] = 0;
    d[S] = 0;
    inq[S] = 1;
    q.push(S);
    while(!q.empty())
    {
        int x = q.front();
        inq[x] = 0;
        q.pop();

        for(auto nxt: edg[x])
            if(cp[x][nxt])
            {
                int dst = d[x] + cst[x][nxt];
                if(dst < d[nxt])
                {
                    d[nxt] = dst;
                    f[nxt] = x;
                    if(!inq[nxt])
                    {
                        inq[nxt] = 1;
                        q.push(nxt);
                    }
                }
            }
    }
}

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

    scanf("%d%d%d", &N, &M, &E);
    K = N + M + 2;
    for(int i = 1; i <= E; i++)
    {
        int x, y, z;
        scanf("%d%d%d", &x, &y, &z);
        y += N;
        cp[x][y] = 1;
        cst[x][y] = z;
        cst[y][x] = -z;
        mch[x][y] = mch[y][x] = i;
        edg[x].push_back(y);
        edg[y].push_back(x);
    }

    S = N + M + 1;
    T = N + M + 2;

    for(int i = 1; i <= N; i++)
    {
        cp[S][i] = 1;
        cst[S][i] = cst[i][S] = 0;
        mch[S][i] = mch[i][S] = -1;
        edg[S].push_back(i);
        edg[i].push_back(S);
    }

    for(int i = N + 1; i <= N + M; i++)
    {
        cp[i][T] = 1;
        cst[i][T] = cst[T][i] = 0;
        mch[i][T] = mch[T][i] = -1;
        edg[T].push_back(i);
        edg[i].push_back(T);
    }

    flow = 0;
    cost = 0;
    while(1)
    {
        BFS();
        if(!f[T])   break;

        int add = 1 << 30;
        int c = 0;
        for(int nod = T; nod != S; nod = f[nod])
        {
            c += cst[ f[nod] ][nod];
            add = min(add, cp[ f[nod] ][nod]);
            if(mch[ f[nod] ][nod] > 0)
                used[ mch[ f[nod] ][nod] ] ^= 1;
        }

        flow += add;
        cost += c;

        for(int nod = T; nod != S; nod = f[nod])
        {
            cp[ f[nod] ][nod] -= add;
            cp[nod][ f[nod] ] += add;
        }
    }

    printf("%d %d\n", flow, cost);
    for(int i = 1; i <= E; i++)
        if(used[i])
            printf("%d ", i);

    return 0;
}