Cod sursa(job #977687)

Utilizator CosminRusuCosmin Rusu CosminRusu Data 26 iulie 2013 13:45:47
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.35 kb
#include <fstream>
#include <vector>
#include <bitset>
#include <queue>
#include <algorithm>
#include <utility>
#include <string.h>

using namespace std;

ifstream cin("cmcm.in");
ofstream cout("cmcm.out");

const int MAXN = 305<<1;
const int MAXM = 105;
const int oo = (1<<31)-1;

typedef vector<int> Graph[MAXN];
typedef vector<int> :: iterator It;

int N, M, E, So, Si, Ans, Flow, MinimumCost;
Graph G;
int Vertex[MAXN][MAXN], Qu[MAXN][MAXN], C[MAXN][MAXN], F[MAXN][MAXN];
priority_queue<pair<int, int>, vector<pair <int, int> > , greater<pair<int, int> > > Q;
vector<int> D(MAXN), Father(MAXN), Old(MAXN), Act(MAXN);

inline bool Dijkstra() {
    fill(D.begin(), D.end(), oo);
    Q.push(make_pair(0, So));
    D[So] = Act[So] = 0;
    while( !Q.empty() ) {
        int Node = Q.top().second;
        int _D = Q.top().first;
        Q.pop();
        if(_D != D[Node]) continue;
        for(It it = G[Node].begin(), fin = G[Node].end() ; it != fin ; ++ it)
            if(F[Node][*it] < Qu[Node][*it]) {
                int act = C[Node][*it] + Old[Node] - Old[*it];
                if(D[*it] > D[Node] + act) {
                    Father[*it] = Node;
                    D[*it] = D[Node] + act;
                    Act[*it] = Act[Node] + C[Node][*it];
                    Q.push(make_pair(D[*it], *it));
                }
            }
    }
    Old = Act;
    return D[Si] != oo;
}

int main()
{
    cin >> N >> M >> E;
    So = 0 ;
    Si = N + M + 1;
    for(int i = 1 ; i <= E ; ++ i) {
        int x, y, z;
        cin >> x >> y >> z;

        Vertex[x][y+N] = i;

        G[x].push_back(N+y);
        G[N+y].push_back(x);

        G[So].push_back(x);
        G[x].push_back(So);

        G[N+y].push_back(Si);
        G[Si].push_back(N+y);

        Qu[x][N+y] = 1;
        Qu[So][x] = 1;
        Qu[y+N][Si] = 1;

        C[x][y+N] = z;
        C[y+N][x] = -z;
    }

    for(; Dijkstra() ; ) {
        for(int i = Si ; i != So ; i = Father[i])
            ++ F[Father[i]][i], --F[i][Father[i]];
        ++ Ans;
        MinimumCost += Act[Si];
    }
    cout << Ans << " " << MinimumCost << "\n";
    for(int i = 1 ; i <= N ; ++ i)
        for(int j = N + 1 ; j <= M+N ; ++ j)
            if(F[i][j] > 0)
                cout << Vertex[i][j] << " ";
    cin.close();
    cout.close();
    return 0;
}