Cod sursa(job #2588314)

Utilizator Mirela_MagdalenaCatrina Mirela Mirela_Magdalena Data 24 martie 2020 17:18:42
Problema Cuplaj maxim de cost minim Scor 20
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.92 kb
#define SMAX 610
#define oo 0x3f3f3f3f
#include <fstream>
#include <cstring>
#include <vector>
#include <queue>
#include <map>
using namespace std;

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




int n, m, e, s, d, p;
int viz[SMAX], t[SMAX], Dmin[SMAX], Ddij[SMAX], Ddij_neg[SMAX];
int cap[SMAX][SMAX], flo[SMAX][SMAX], cost[SMAX][SMAX];
vector<int> graph[SMAX], mfin;
map<pair<int, int>, int> mapi;


struct muc{
    int my_node, d;

    bool operator<(const muc &other) const{
        if(d != other.d)
            return d > other.d;
        return my_node > other.my_node;

    }
};


void read()
{
    int x, y;
    f>>n>>m>>e;
    for(int i = 1; i <= e; ++i)
    {
        f>>x>>y>>p;
        y += n;
        mapi[{x, y}] = i;
        cap[x][y] = 1;
        cap[y][x] = 0;

        cost[x][y] = p;
        cost[y][x] = -p;

        graph[x].push_back(y);
        graph[y].push_back(x);
    }

    for(int j = 1; j <= n; ++j)
    {
        cap[0][j] = 1;
        cap[j][0] = 0;
        cost[0][j] = 0;
        cost[j][0] = 0;

        graph[0].push_back(j);
        graph[j].push_back(0);
    }
    int d = n + m + 1;
    for(int j = n+1; j <= n+m; ++j)
    {

        cap[j][d] = 1;
        cap[d][j] = 0;
        cost[j][d] = 0;
        cost[d][d] = 0;

        graph[j].push_back(d);
        graph[d].push_back(j);
    }

    /**int x, y, c, p;
    f>>n>>m>>s>>d;

    for(int i = 1; i <= m; ++i)
    {
        f>>x>>y>>c>>p;
        cap[x][y] = c;
        cap[y][x] = 0;

        cost[x][y] = p;
        cost[y][x] = -p;

        graph[x].push_back(y);
        graph[y].push_back(x);
    }**/
}

void bellman_ford()
{
    queue<int> Q;
    memset(Dmin, oo, sizeof(Dmin));
    Q.push(s);
    Dmin[s] = 0;
    viz[s] = 1;

    while(!Q.empty())
    {
        int from = Q.front();
        Q.pop();
        viz[from] = 0;

        for(auto &v:graph[from])
            if(cap[from][v] - flo[from][v] != 0 && Dmin[v] > Dmin[from] + cost[from][v])
            {
                Dmin[v] = Dmin[from] + cost[from][v];
                if(viz[v] == 0)
                {
                    Q.push(v);
                    viz[v] = 1;
                }
            }
    }
}



bool dijkstra()
{
    priority_queue<muc> Q;
    memset(viz, 0, sizeof(viz));
    memset(Ddij, oo, sizeof(Ddij));
    memset(Ddij_neg, oo, sizeof(Ddij_neg));

    Q.push({s, 0});
    Ddij[s] = 0;
    Ddij_neg[s] = 0;

    while(!Q.empty())
    {
        muc from = Q.top();
        Q.pop();
        if(viz[from.my_node] == 1)
            continue;
        viz[from.my_node] = 1;

        for(auto &v:graph[from.my_node])
            if(cap[from.my_node][v] - flo[from.my_node][v] > 0)
            {
                int new_cost = cost[from.my_node][v] + Dmin[from.my_node] - Dmin[v];
                if(Ddij[v] > Ddij[from.my_node] + new_cost)
                {
                    t[v] = from.my_node;
                    Ddij[v] = Ddij[from.my_node] + new_cost;
                    Ddij_neg[v] = Ddij_neg[from.my_node] + cost[from.my_node][v];
                    Q.push({v, Ddij[v]});
                }
            }
    }
    memcpy(Dmin, Ddij_neg, sizeof(Ddij_neg));
    return Ddij[d] != oo;
}





int main()
{
    int dm = 0;
    read();
    s = 0;
    d = n + m + 1;
    bellman_ford();

    int edges = 0;
    while(dijkstra())
    {
        int act_flomax = oo;
        for(int v = d; v != s; v = t[v])
            act_flomax = min(act_flomax, cap[t[v]][v] - flo[t[v]][v]);
        int nv = t[d], nu = t[nv];
        mfin.push_back(mapi[{nu, nv}]);

        for(int v = d; v != s; v = t[v])
        {
            flo[t[v]][v] += act_flomax;
            flo[v][t[v]] -= act_flomax;
        }
        dm += Dmin[d]*act_flomax;
        edges++;

    }
    g<<edges<<" "<<dm<<'\n';
    for(auto &v:mfin)
        g<<v<<" ";
    return 0;
}