Cod sursa(job #2631351)

Utilizator cyg_vladioanBirsan Vlad cyg_vladioan Data 30 iunie 2020 09:21:52
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.66 kb
#include <cstdio>
#include <vector>
#include <queue>
#include <cstring>
#include <algorithm>
using namespace std;
const int INF = 2.e9;
const int VMAX = 600;
const int EMAX = 50000;
vector <int> G[VMAX + 5];
int cf[VMAX + 5][VMAX + 5] , cst[VMAX + 5][VMAX + 5] , d[VMAX + 5] , dist[VMAX + 5] , new_dist[VMAX + 5] , p[VMAX + 5] , V;
struct muchii
{
    int x , y;
    muchii(int tx = 0 , int ty = 0)
    {
        x = tx;
        y = ty;
    }
};
muchii mch[EMAX + 5];
void bellmanford(int s)
{
    int u , v , i;
    for(i = 0 ; i <= V + 1 ; i ++)
        dist[i] = INF;
    dist[s] = 0;
    queue <int> q;
    q.push(s);
    while(!q.empty())
    {
        u = q.front();
        q.pop();
        for(i = 0 ; i < G[u].size() ; i ++)
        {
            v = G[u][i];
            if(cf[u][v] && dist[v] > dist[u] + cst[u][v])
            {
                dist[v] = dist[u] + cst[u][v];
                q.push(v);
            }
        }
    }
}
struct path
{
    int nod , cost;
    path(int x = 0 , int y = 0)
    {
        nod = x;
        cost = y;
    }
};
bool operator<(const path& a , const path& b)
{
    return a.cost > b.cost;
}
int dijkstra(int s , int t)
{
    int i , u , v , cost , new_cost;
    for(i = 0 ; i <= V + 1 ; i ++)
        d[i] = INF;
    d[s] = 0;
    priority_queue <path> pq;
    pq.push(path(s , 0));
    while(!pq.empty())
    {
        u = pq.top().nod;
        cost = pq.top().cost;
        pq.pop();
        if(cost > d[u])
            continue;
        for(i = 0 ; i < G[u].size() ; i ++)
        {
            v = G[u][i];
            if(cf[u][v])
            {
                new_cost = d[u] + cst[u][v] + dist[u] - dist[v];
                if(new_cost < d[v])
                {
                    d[v] = new_cost;
                    new_dist[v] = new_dist[u] + cst[u][v];
                    p[v] = u;
                    pq.push(path(v , new_cost));
                }
            }
        }
    }
    memcpy(dist , new_dist , sizeof(new_dist));
    if(d[t] == INF)
        return 0;
    return 1;
}
int get_flow(int s , int t)
{
    int nod , flow;
    flow = INF;
    for(nod = t ; nod != s ; nod = p[nod])
        flow = min(flow , cf[p[nod]][nod]);
    return flow;
}
int set_flow(int s , int t , int flow)
{
    for(int nod = t ; nod != s ; nod = p[nod])
    {
        cf[p[nod]][nod] -= flow;
        cf[nod][p[nod]] += flow;
    }
    return flow * dist[t];
}
void cmcm(int s , int t)
{
    int cost , flow , new_flow;
    cost = flow = 0;
    while(dijkstra(s , t))
    {
        new_flow = get_flow(s , t);
        if(new_flow)
            cost += set_flow(s , t , new_flow);
        flow += new_flow;
    }
    printf("%d %d\n" , flow , cost);
}
int main()
{
    freopen("cmcm.in" , "r" , stdin);
    freopen("cmcm.out" , "w" , stdout);
    int n , m , e , i , x , y , z , s , t;
    scanf("%d%d%d" , &n , &m , &e);
    for(i = 1 ; i <= e ; i ++)
    {
        scanf("%d%d%d" , &x , &y , &z);
        G[x].push_back(y + n);
        G[y + n].push_back(x);
        cf[x][y + n] = 1;
        cst[x][y + n] = z;
        cst[y + n][x] = -z;
        mch[i] = muchii(x , y);
    }
    V = n + m;
    for(i = 1 ; i <= n ; i ++)
    {
        G[0].push_back(i);
        G[i].push_back(0);
        cf[0][i] = 1;
    }
    for(i = 1 ; i <= m ; i ++)
    {
        G[i + n].push_back(V + 1);
        G[V + 1].push_back(i + n);
        cf[i + n][V + 1] = 1;
    }
    s = 0;
    t = V + 1;
    bellmanford(s);
    cmcm(s , t);
    for(i = 1 ; i <= e ; i ++)
        if(cf[mch[i].x][mch[i].y + n] == 0)
            printf("%d " , i);
    return 0;
}