Cod sursa(job #3201357)

Utilizator RobertAcAcatrinei Robert-Marian RobertAc Data 7 februarie 2024 18:57:17
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.38 kb
#include <bits/stdc++.h>
#ifdef LOCAL
#define in cin
#define out cout
#endif

using namespace std;

#ifndef LOCAL
ifstream in("cmcm.in");
ofstream out("cmcm.out");
#endif

const int nmax = 605;
const int inf = 1e9;

vector<int> adj[nmax];
int s, d;

struct edge
{
    int fr, to, c, w, ind;
    edge(int fr = 0, int to = 0, int c = 0, int w = 0, int ind = -1) : fr(fr), to(to), c(c), w(w), ind(ind) {}
} edges[nmax * nmax];

int cnt = 0;

void addE(int a, int b, int c, int w, int ind)
{
    // cerr << a << ' ' << b << ' ' << w << '\n';
    adj[a].push_back(cnt);
    adj[b].push_back(cnt + 1);
    edges[cnt] = edge(a, b, c, w, ind);
    edges[cnt + 1] = edge(b, a, 0, -w, -1);
    cnt += 2;
}

int pi[nmax];
int dist[nmax];
bool inq[nmax];
int enter[nmax];

void resetDist()
{
    for (int i = s; i <= d; i++)
        dist[i] = inf;
}

void topi()
{
    for (int i = s; i <= d; i++)
    {
        pi[i] += dist[i];
    }
}

struct dijkstate
{
    int a, b;
    dijkstate(int a, int b) : a(a), b(b) {}
    bool operator<(const dijkstate &other) const
    {
        return b > other.b;
    }
};

int trans(int a, int b, int w)
{
    //cerr<<a<<' '<<b<<' '<<w<<'\n';
    return a + w - b;
}

bool dijkstra()
{
    resetDist();
    priority_queue<dijkstate> pq;
    pq.push({s, 0});
    dist[s] = 0;
    while (!pq.empty())
    {
        auto nod = pq.top();
        pq.pop();
        if (dist[nod.a] < nod.b)
            continue;
        for (auto i : adj[nod.a])
        {
            if(edges[i].c==0)continue;
            //cerr<<nod.a<<' '<<edges[i].to<<'\n';
            int rw = trans(pi[nod.a], pi[edges[i].to], edges[i].w);
            //cerr<<rw<<'\n';
            if (dist[edges[i].to] > dist[nod.a] + rw)
            {
                dist[edges[i].to] = dist[nod.a] + rw;
                pq.push({edges[i].to, dist[edges[i].to]});
                enter[edges[i].to] = i;
            }
        }
    }
    if (dist[d] == inf)
        return 0;
    topi();
    return 1;
}

void bellmanford()
{
    resetDist();
    dist[s] = 0;
    queue<int> q;
    q.push(s);
    inq[s] = 1;
    while (!q.empty())
    {
        int nod = q.front();
        q.pop(); // cerr<<nod<<'\n';
        inq[nod] = 0;
        for (int i : adj[nod])
        {
            if (edges[i].c != 0 && dist[edges[i].to] > dist[nod] + edges[i].w)
            {
                dist[edges[i].to] = dist[nod] + edges[i].w;
                if (!inq[edges[i].to])
                {
                    inq[edges[i].to] = 1;
                    q.push(edges[i].to);
                }
            }
        }
    }
    topi();
}

int dfs(int node)
{
    if (node == 0)
        return 0;
    int ind = enter[node];
    edges[ind].c--;
    edges[ind ^ 1].c++;
    return edges[ind].w + dfs(edges[ind].fr);
}

int main()
{
    int n, m, e;
    in >> n >> m >> e;
    s = 0;
    d = n + m + 1;
    for (int i = 1; i <= n; i++)
    {
        addE(0, i, 1, 0, -1);
    }
    for (int i = 1; i <= m; i++)
    {
        addE(n + i, n + m + 1, 1, 0, -1);
    }
    for (int i = 1; i <= e; i++)
    {
        int a, b, w;
        in >> a >> b >> w;
        addE(a, b + n, 1, w, i);
    }
    int cst = 0;
    int res = 0;
    bellmanford();
    while (dijkstra())
    {
        res++;
        cst += dfs(d);
        if (res > 1e4)
            break;
    }
    out << res<<' '<<cst<<'\n';
    for(int i=0;i<cnt;i++)
    {
        if(edges[i].c==0&&edges[i].ind!=-1)out<<edges[i].ind<<' ';
    }
}