Cod sursa(job #1893890)

Utilizator mirupetPetcan Miruna mirupet Data 26 februarie 2017 10:39:08
Problema Cuplaj maxim de cost minim Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 2.58 kb
#include<cstdio>
#include<vector>
#include<queue>
#include<set>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;

FILE *fin = freopen("cmcm.in", "r", stdin);
FILE *fout = freopen("cmcm.out", "w", stdout);

const int INF = 0x3fffffff;;
const int MAX_N = 300;
const int DIM = MAX_N * 2 + 1;
int N, M, S, D, E, cnt;
int dist[DIM], fromWhere[DIM];
int carry[DIM][DIM], cost[DIM][DIM];
long long ans;
bool used[MAX_N];
vector < int > v[MAX_N];
vector < pair < int, int > > edge;
queue < int > q;
set < int > sol;

bool BellmanFord()
{
    for (int i = S; i <= D; i++)
        dist[i] = INF,
        fromWhere[i] = -1,
        used[i] = 0;

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

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

        vector < int > :: iterator it;
        for (it = v[p].begin(); it != v[p].end(); it++)
            if (carry[p][*it] > 0 && dist[*it] > dist[p] + cost[p][*it])
            {
                dist[*it] = dist[p] + cost[p][*it];
                fromWhere[*it] = p;
                if (!used[*it])
                {
                    used[*it] = 1;
                    q.push(*it);
                }
            }
    }

    if (dist[D] == INF)
        return 0;

    if (dist[D] != INF)
    {
        for (int i = D; i != S; i = fromWhere[i])
        {
            carry[fromWhere[i]][i] --;
            carry[i][fromWhere[i]] ++;

            ans += 1LL * cost[fromWhere[i]][i];
        }
        return 1;
    }
}

int main()
    {
        scanf("%d%d%d", &N, &M, &E);
        S = 0, D = M + N + 1;
        for (int i = 1, X, Y, C; i <= E; i++)
        {
            scanf("%d%d%d", &X, &Y, &C);
            Y += N;
            v[X].push_back(Y);
            v[Y].push_back(X);

            carry[X][Y] = 1;
            cost[X][Y] = C;
            cost[Y][X] = -C;

            edge.push_back(make_pair(X, Y));
        }

        for (int i = 1; i <= N; i++)
        {
            v[S].push_back(i);
            v[i].push_back(S);
            carry[S][i] = 1;
        }

        for (int i = N + 1; i <= N + M; i++)
            v[D].push_back(i),
            v[i].push_back(D),
            carry[i][D] = 1;

        while (BellmanFord())
            cnt++;
        printf("%d %lld\n", cnt, ans);

        vector < pair < int, int > > :: iterator it;
        for (it = edge.begin(); it != edge.end(); it++)
            if (!carry[it -> first][it -> second])
                printf("%d ", it - edge.begin() + 1);
    }