Cod sursa(job #2479239)

Utilizator uvIanisUrsu Ianis Vlad uvIanis Data 23 octombrie 2019 16:31:08
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.64 kb
#include <bits/stdc++.h>
#define NMAX 305
using namespace std;

ifstream fin("cmcm.in");
ofstream fout("cmcm.out");

int n, m, e;

vector<int> GRAPH[2*NMAX];

int CAPACITY[610][610], FLOW[610][610], COST[610][610], indice[610][610], source = 0, destinaton = 609;

int dist[2*NMAX], cntInPQ[2*NMAX], tata[2*NMAX];
bool inPQ[2*NMAX];

struct comp{
    bool operator () (int a, int b)
    {
        return dist[a] > dist[b];
    }
};


bool minDist()
{
    fill(dist, dist + 2*NMAX, 2000000000);
    fill(cntInPQ, cntInPQ + 2*NMAX, 0);

    dist[source] = 0;

    priority_queue<int, vector<int>, comp> PQ;

    PQ.push(source);

    while(!PQ.empty())
    {
        int node = PQ.top();
        PQ.pop();

        inPQ[node] = false;

        cntInPQ[node]++;

        if(cntInPQ[node] > n + m + 2) return false;


        for(int next : GRAPH[node])
        {
            if(CAPACITY[node][next] == FLOW[node][next]) continue;

            if(dist[node] + COST[node][next] < dist[next])
            {
                dist[next] = dist[node] + COST[node][next];

                tata[next] = node;

                if(inPQ[next] == false)
                {
                    inPQ[next] = true;
                    PQ.push(next);
                }
            }
        }
    }

    if(dist[destinaton] == 2000000000) return false;

    return true;
}

int main()
{
    fin >> n >> m >> e;

    int x, y, c;

    for(int i = 1; i <= e; ++i)
    {
        fin >> x >> y >> c;

        GRAPH[x].push_back(y + 300);
        GRAPH[y + 300].push_back(x);

        indice[x][y + 300] = i;

        CAPACITY[x][y + 300] = 1;
        COST[x][y + 300] = c;
        COST[y + 300][x] = -c;
    }

    for(int i = 1; i <= n; ++i)
    {
        GRAPH[source].push_back(i);
        GRAPH[i].push_back(source);

        CAPACITY[source][i] = 1;
    }

    for(int i = 1; i <= m; ++i)
    {
        GRAPH[i + 300].push_back(destinaton);
        GRAPH[destinaton].push_back(i + 300);

        CAPACITY[i + 300][destinaton] = 1;
    }

    int mincost = 0;

    while(minDist())
    {
        for(int i = destinaton; i != source; i = tata[i])
        {
            mincost += COST[tata[i]][i];

            ++FLOW[tata[i]][i];
            --FLOW[i][tata[i]];
        }
    }

    int cnt = 0;

    for(int node : GRAPH[destinaton]) if(FLOW[node][destinaton] == 1) ++cnt;

    fout << cnt << " " << mincost << "\n";

    for(int i = 1; i <= 300 + m; ++i)
    {
        for(int j = 1; j <= 300 + m; ++j)
        {
            if(FLOW[i][j] == 1) fout << indice[i][j] << " ";
        }
    }

}