Cod sursa(job #2256679)

Utilizator SqueekDanielTodasca Daniel SqueekDaniel Data 8 octombrie 2018 22:30:57
Problema Cuplaj maxim de cost minim Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 2.89 kb
#include <bits/stdc++.h>

#define MaxN 305
#define inf  (int)(1e9)

std::ifstream InFile("cmcm.in");
std::ofstream OutFile("cmcm.out");

int E;
std::priority_queue <std::pair <int, int>, std::vector <std::pair <int, int>>, std::greater <std::pair <int, int>>> PQueue;
std::pair <int, int> Top;
std::queue <int> Queue;
bool InQueue[MaxN];

class DirectedGraph {
public:
    int EdgeIndex[MaxN][MaxN];
    int NMatches, FlowCost;
    int N, L, R, S, D;

    inline void AddEdge(int x, int y, int c, int z) {
        Node[x].ADC.push_back(y);
        Node[y].ADC.push_back(x);
        Capacity[x][y] = c;
        Cost[x][y] = z;
        Cost[y][x] =-z;
    }

    void CreateNetwork() {
        S = 0; N = L+R+2; D = N-1;
        for (int i=0; i<L; ++i)
            Node[S].ADC.push_back(i+1),
            Capacity[S][i+1] = 1;
        for (int i=L; i<L+R; ++i)
            Node[i+1].ADC.push_back(D),
            Capacity[i+1][D] = 1;
    }

    inline bool BellmanFord() {
        for (int i=0; i<N; ++i)
            Dist[i] = inf;
        Dist[S] = 0;

        Queue.push(S);
        InQueue[S] = 1;

        int Front;
        while (!Queue.empty()) {
            Front = Queue.front();
            Queue.pop();

            InQueue[Front] = 0;
            for (auto Vecin:Node[Front].ADC)
                if (Dist[Front] + Cost[Front][Vecin] < Dist[Vecin] && Capacity[Front][Vecin]) {
                    Dist[Vecin] = Dist[Front] + Cost[Front][Vecin];
                    Parent[Vecin] = Front;
                    if (!InQueue[Vecin])
                        InQueue[Vecin] = 1,
                        Queue.push(Vecin);
                }
        }
        if (Dist[D] == inf) return false;

        int x = D;
        while(x != S) {
            Capacity[Parent[x]][x] ^= 1;
            Capacity[x][Parent[x]] = 1;
            FlowCost += Cost[Parent[x]][x];
            x = Parent[x];
            if(Parent[x] <= L) Sol[Parent[x]] = x-L;
        }   return true;
    }

    void Print() {
        for (int i=0; i<L; ++i)
            if (Sol[i+1])
                NMatches++;
        OutFile << NMatches << ' ' << FlowCost << '\n';
        for (int i=0; i<L; ++i)
            if (Sol[i+1])
                OutFile << EdgeIndex[i+1][Sol[i+1]] << ' ';
    }

private:
    int Parent[MaxN],
        Sol[MaxN];
    int Dist[MaxN];
    int Cost[MaxN][MaxN],
        Capacity[MaxN][MaxN];

    struct GraphNode {
        std::vector <int> ADC;
    }   Node[MaxN];

}   Graph;

void Rezolvare() {
    Graph.CreateNetwork();
    while (Graph.BellmanFord());
    Graph.Print();
}

void Citire() {
    InFile >> Graph.L >> Graph.R >> E;
    for (int i=0, x, y, c; i<E; ++i)
        InFile >> x >> y >> c,
        Graph.EdgeIndex[x][y] = i+1,
        Graph.AddEdge(x, y+Graph.L, 1, c);
}

int main() {
    Citire();
    Rezolvare();

    return 0;
}