Cod sursa(job #1800400)

Utilizator heracleRadu Muntean heracle Data 7 noiembrie 2016 19:10:39
Problema Cc Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.65 kb
#include <fstream>
#include <queue>
#include <iostream>
#include <vector>
using namespace std;

struct a
{
    int c, t, nod;
    a() {}
    a(int _c, int _nod, int _t) : c(_c), t(_t), nod(_nod) {}

    bool operator< (const a & q) const {
        return (c > q.c);
    }
};

int cost[1000][1000];
int flux[1000][1000];
int rez[1000][1000];
int n; /// 1 sursa, n destinatie
int tata[1000];
int viz[1000];

void solve_flux();
int ask();
bool dijk();
void update(int muchie);

int main()
{
    ifstream in("cc.in");
    int m;
    in >> m;
    n = 2 * m + 2;

    for (int i = 2; i <= m + 1; i++) {
        flux[1][i] = 1;
        cost[1][i] = 0;
        for (int j = m + 2; j < 2 * m + 2; j++) {
            in >> cost[i][j];
            cost[j][i]=-cost[i][j];
            flux[i][j] = 1;
        }
    }

    for (int i = m + 2; i < 2 * m + 2; i++)
        flux[i][2 * m + 2] = 1, cost[i][2 * m + 2] = 0;


    solve_flux();

    int r = 0;

    for (int i = 2; i <= m + 1; i++)
        for (int j = m + 2; j < n; j++)
            if (rez[i][j] == 1)
            {
                r += cost[i][j];
               // cerr<<i-1<<" "<<j-m-1<<" "<<cost[i][j]<<"\n";
            }

    ofstream out("cc.out");
    out << r;

    return 0;
}

int ask()
{
    int minim = 1e9, p;
    for (int i = n; i != 1; i = tata[i]) {
        if (flux[tata[i]][i] - rez[tata[i]][i] < minim)
            minim = flux[tata[i]][i] - rez[tata[i]][i], p = i;
    }
    return minim;
}

void update(int muchie)
{
    for (int i = n; i != 1; i = tata[i]) {
        rez[tata[i]][i] += muchie;
        rez[i][tata[i]] -= muchie;

        cerr<<tata[i]<<"=tata "<<i<<"=i "<<muchie<<"\n";
    }
}

bool dijk()
{
    for (int i = 2; i <= n; i++)
        viz[i] = tata[i] = 1e9;

    priority_queue <a> p; /// first -> cost / second.first -> nod / second.second -> from
    tata[1] = -1;

    p.push({ 0,  1, -1 });
    while (!p.empty()) {
        int nod = p.top().nod, c = p.top().c, t = p.top().t;
       // cerr<<nod<<"\n";
        p.pop();

        if (c > viz[nod])
            continue;

        tata[nod] = t;

        if (nod == n)
            return true;

        for (int i = 1; i <= n; i++) {
            if (flux[nod][i] - rez[nod][i] > 0  && cost[nod][i] + c < viz[i]) {
                p.push({ cost[nod][i] + c, i, nod });
                viz[i] = cost[nod][i] + c;
            }
        }
    }
    return false;
}

void solve_flux()
{
    while (dijk()) {
        int min_muchie = ask();
        update(min_muchie);
        cerr<<"\n\n";

        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=n; j++)
            {
                cerr<<rez[i][j]<<" ";
            }
            cerr<<"\n";
        }
    }
}