Cod sursa(job #2126772)

Utilizator KemyKoTeo Virghi KemyKo Data 9 februarie 2018 22:47:29
Problema Cuplaj maxim de cost minim Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 3.69 kb
#include <fstream>
#include <vector>
#include <queue>
#include <cstring>
#define NMAX 301
#define INF 0x3f3f3f3f

using namespace std;

ifstream f("cmcm.in");
ofstream g("cmcm.out");

struct muchie{int cost, leg, index;};

int n, m, nrSt, nrDr, SZ, CMIN, FC, nr;
int C[NMAX][NMAX], F[NMAX][NMAX];
int dist[NMAX], dst[NMAX], D[NMAX], t[NMAX];
bool viz[NMAX];
vector < muchie > v[NMAX];  //cost + muchie
priority_queue < pair<int, int>, vector< pair<int, int> >, greater< pair<int, int> > > H;   //heap

void buildGraph()
{
    int cst, x, y, i;
    muchie aux;

    f>>nrSt>>nrDr>>m;
    n = nrSt + nrDr + 2;
    SZ = (n + 1) * sizeof(int);
    for(i=1;i<=m;++i){
        f>>x>>y>>cst;
        ++x;
        y += nrSt + 1;

        v[x].push_back({cst, y, i});
        v[y].push_back({-cst, x, i});

        v[1].push_back({0, x, -1});  //S -> st
        v[x].push_back({0, 1, -1});

        v[y].push_back({0, n, -1});  //dr -> D
        v[n].push_back({0, y, -1});
        C[x][y] = C[1][x] = C[y][n] = 1;
    }
}

void bellman(int s, int d)
{
    int i, nod, vec, cst, sz;
    queue <int> Q;

    memset(dist, INF, SZ);
    viz[s] = true;
    dist[s] = 0;
    Q.push(s);
    while(!Q.empty()){
        nod = Q.front();
        Q.pop();
        viz[nod]=false;

        sz = v[nod].size();
        for(i=0;i<sz;++i){
            vec = v[nod][i].leg;
            cst = v[nod][i].cost;

            if(dist[vec] > dist[nod] + cst && C[nod][vec] > F[nod][vec]){
                dist[vec] = dist[nod] + cst;

                if(vec!=d && !viz[vec]){
                    viz[vec] = true;
                    Q.push(vec);
                }
            }
        }
    }
}

bool dijkstra(int s, int d)
{
    int i, nod, vec, cst, cstVec, sz;

    memset(dst, INF, SZ);
    memset(t, 0, SZ);

    dst[s] = D[s] = 0;
    t[s] = -1;
    H.push(make_pair(0, s));
    while(!H.empty()){
        nod = H.top().second;
        cst = H.top().first;
        H.pop();

        if(nod==d || cst != dst[nod])
            continue;

        sz = v[nod].size();
        for(i=0;i<sz;++i){
            vec = v[nod][i].leg;
            cstVec = v[nod][i].cost;

            if(dst[vec] > cst + cstVec + dist[nod] - dist[vec] && C[nod][vec] > F[nod][vec]){
                dst[vec] = cst + cstVec + dist[nod] - dist[vec];
                D[vec] = cstVec + D[nod];
                t[vec] = nod;

                H.push(make_pair(dst[vec], vec));
            }
        }
    }

    memcpy(dist, D, SZ);

    if(t[d]) return true;
    return false;
}

int cost(int x, int y)
{
    int i, sz;

    sz = v[x].size();
    for(i=0;i<sz;++i)
        if(v[x][i].leg == y)
            return v[x][i].cost;
    return 0;
}

int main()
{
    int i, j;
    buildGraph();   //citire

    bellman(1, n);  //solve
    while(dijkstra(1, n)){
        FC = INF;

        for(i=n;i!=1;i=t[i])
            FC = min(FC, C[t[i]][i] - F[t[i]][i]);

        for(i=n;i!=1;i=t[i]){
            F[t[i]][i] += FC;
            F[i][t[i]] -= FC;

            CMIN += FC * cost(t[i], i);
        }
    }

    for(i=2;i<n;++i){   //afis
        int sz = v[i].size();
        for(j=0;j<sz;++j){
            if(v[i][j].leg!=n && C[i][v[i][j].leg] && F[i][v[i][j].leg])
                nr++;
            //if(F[i][v[i][j].leg])cout<<i<<' '<<v[i][j].leg<<' '<<F[i][v[i][j].leg]<<' '<<v[i][j].index<<'\n';
        }
    }
    g<<nr<<' '<<CMIN<<'\n';
    for(i=2;i<n;++i){
        int sz = v[i].size();
        for(j=0;j<sz;++j)
            if(v[i][j].leg!=n && C[i][v[i][j].leg] && F[i][v[i][j].leg])
                g<<v[i][j].index<<' ';
    }
    g.close();
    return 0;
}