Cod sursa(job #2351843)

Utilizator silviu982001Borsan Silviu silviu982001 Data 22 februarie 2019 19:04:02
Problema Cuplaj maxim de cost minim Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.18 kb
#include <fstream>
#include <bitset>
#include <vector>
#include <queue>
#include <unordered_map>


using namespace std;

int n, m, e;
bitset<610> inQ;
int c[610][610], old[610], dist[610], real[610], p[610], d, maxFlow, minCost;
vector<int> v[610];
unordered_map<unsigned long, int> id;

inline int pairF(int x, int y)
{
    return (0.5 * (x+y)*(x+y+1) +x);
}


void belmanFord()
{
    memset(old, 0x0f0f0f0f, sizeof(old));
    queue<int> q;
    for(q.push(1), inQ[1]=1, old[1]=0; !q.empty();)
    {
        int nod = q.front();
        q.pop();
        inQ[nod]=0;
        for (auto it = v[nod].begin(); it != v[nod].end(); ++it)
        {
            if (c[nod][*it] && old[*it] > old[nod] + c[nod][*it])
            {
                old[*it] = old[nod] + c[nod][*it];
                if (inQ[*it]==0)
                {
                    inQ[*it]=1;
                    q.push(*it);
                }
            }
        }
    }
}

bool dijkastra()
{
    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> H;
    memset(dist, 0x0f0f0f0f, sizeof(dist));
    memset(p, 0, sizeof(p));
    for(dist[1]=0, real[1]=0, H.push({0, 1}); !H.empty();)
    {
        int d = H.top().first;
        int nod = H.top().second;
        H.pop();
        if (d > dist[nod])
            continue;
        
        for (auto it = v[nod].begin(); it != v[nod].end(); ++it)
            if (c[nod][*it])
            {
                int newCost = d + c[nod][*it] + old[nod] - old[*it];
                if (newCost < dist[*it])
                {
                    dist[*it] = newCost;
                    real[*it] = real[nod] + c[nod][*it];
                    p[*it]=nod;
                    H.push({dist[*it], *it});
                }
            }
    }
    
    if (p[d] == 0)
        return false;
    
    memcpy(old, real, sizeof(old));
    
    int minFlow = INT_MAX;
    for (int nod = d; nod != 1; nod=p[nod])
        minFlow = min(minFlow, c[p[nod]][nod]);
    
    for (int nod = d; nod != 1; nod=p[nod])
    {
        c[p[nod]][nod] -= minFlow;
        c[nod][p[nod]] += minFlow;
    }
    
    maxFlow += minFlow;
    minCost += minFlow * real[d];
    
    return true;
}

int main()
{
    int x,y,cost;
    ifstream fin("cmcm.in");
    fin >> n >> m >> e;
    for (int i = 0; i < e; ++i)
    {
        fin >> x >> y >> cost;
        ++x;
        y+=n+1;
        v[x].push_back(y);
        v[y].push_back(x);
        c[x][y]=cost;
        c[y][x]=-cost;
        id[pairF(x, y)] = i;
    }
    fin.close();
    for(int i = 1; i <= n+1; ++i)
    {
        v[1].push_back(i);
        v[i].push_back(1);
        c[1][i]=c[i][1]=0;
    }
    d = n+m+2;
    for (int i = n+2; i < d; ++i)
    {
        v[i].push_back(d);
        v[d].push_back(i);
        c[i][d]=c[d][i]=0;
        c[i][d]=1;
    }
    belmanFord();
    for(;dijkastra(););
    int result = 0;
    for (int i = 2; i <= n+1; ++i)
        for (int j = n+2; j < n+m+2; ++j)
            if (c[i][j])
                ++result;
    ofstream fout("cmcm.out");
    fout << result << " " << minCost << '\n';
    for (int i = 2; i <= n+1; ++i)
        for (int j = n+2; j < n+m+2; ++j)
            if (c[i][j])
                fout << id[pairF(i, j)] << ' ';
    return 0;
}