Cod sursa(job #1871384)

Utilizator borcanirobertBorcani Robert borcanirobert Data 7 februarie 2017 12:23:09
Problema Cuplaj maxim de cost minim Scor 80
Compilator cpp Status done
Runda Arhiva educationala Marime 3.6 kb
#include <fstream>
#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#include <cstring>
using namespace std;

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

struct Nod{
    int cost, nod;

    bool operator < ( const Nod& a ) const
    {
        return cost > a.cost;
    }
};
using VI = vector<int>;
const int MAX = 2*305;
const int Inf = 0x3f3f3f3f;
vector<VI> G;
VI Cost, RealCost, P, t;
int m[MAX][MAX];
int C[MAX][MAX];
int F[MAX][MAX];
int N, M, K;
int n;
int cmin, nm;
bool u[MAX];
int ind[MAX][MAX];

void ReadGraph();
void Bellmand_Ford();
bool Dijkstra();

int main()
{
    ReadGraph();

   /* for ( int i = 0; i <= N; ++i )
    {
        cout << "Pt. " << i << ": ";
        for ( const int& x : G[i] )
            cout << x << ' ';
        cout << '\n';
    }   */

    Bellmand_Ford();

    while ( Dijkstra() );

    for ( int i = 1; i <= n; ++i )
        for ( int j = n + 1; j < N; ++j )
            if ( C[i][j] && F[i][j] )
            {
                ++nm;
                break;
            }

    fout << nm << ' ' << cmin << '\n';
    for ( int i = 1; i <= n; ++i )
        for ( int j = n + 1; j < N; ++j )
            if ( C[i][j] && F[i][j] )
            {
                fout << ind[i][j] << ' ';
            }

    fin.close();
    fout.close();
    return 0;
}

void ReadGraph()
{
    int x, y, z;

    fin >> N >> M >> K; n = N;
    G = vector<vector<int>>(N + M + 2);
    for ( int i = 1; i <= K; ++i )
    {
        fin >> x >> y >> z;
        G[x].push_back(N + y);
        G[N + y].push_back(x);
        ind[x][N + y] = i;

        C[x][N + y] = 1;

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

    for ( int i = 1; i <= N; ++i )
    {
        G[0].push_back(i);
        G[i].push_back(0);
        C[0][i] = 1;
    }

    for ( int i = N + 1; i <= N + M; ++i )
    {
        G[i].push_back(N + M + 1);
        G[N + M + 1].push_back(i);
        C[i][N + M + 1] = 1;
    }

    N += M + 1;
}

void Bellmand_Ford()
{
    queue<int> Q;
    P = VI(N + 1, Inf);
    P[0] = 0;
    Q.push(0);

    while ( !Q.empty() )
    {
        int x = Q.front();
        Q.pop();

        for ( const auto& y : G[x] )
            if ( C[x][y] )
            {
                int c_nou = P[x] + m[x][y];
                if ( c_nou > P[y] ) continue;

                P[y] = c_nou;
                Q.push(y);
            }
    }

   /* for ( int i = 1; i <= N; ++i )
        cout << "Costul de la 0 la " << i << " = " << P[i] << '\n'; */
}

bool Dijkstra()
{
    priority_queue<Nod> Q;
    Cost = RealCost = VI(N + 1, Inf);
    t = VI(N + 1);
    Cost[0] = RealCost[0] = 0;
    Q.push({0, 0});

    while ( !Q.empty() )
    {
        int x = Q.top().nod;
        int c0 = Q.top().cost;
        Q.pop();

        if ( c0 != Cost[x] ) continue;

        for ( const auto& y : G[x] )
            if ( C[x][y] - F[x][y] > 0 )
            {
                int c_nou = Cost[x] + m[x][y] + P[x] - P[y];
                if ( c_nou >= Cost[y] ) continue;

                Cost[y] = c_nou;
                RealCost[y] = RealCost[x] + m[x][y];
                t[y] = x;
                Q.push({Cost[y], y});
            }
    }

    P = RealCost;

    if ( Cost[N] >= Inf ) return false;

    int fc = 1;
    for ( int i = N; i != 0; i = t[i] )
        fc = min( fc, C[t[i]][i] - F[t[i]][i] );

    if ( !fc ) return false;

    cmin += RealCost[N];
    for ( int i = N; i != 0; i = t[i] )
    {
        F[t[i]][i]++;
        F[i][t[i]]--;
    }
}