Cod sursa(job #3326689)

Utilizator stanciuvalentinStanciu-Tivlea Valentin Gabriel stanciuvalentin Data 29 noiembrie 2025 22:58:37
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.07 kb
#include <bits/stdc++.h>

using namespace std;

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

struct date{
    int node, cost;
};

struct compare{
    bool operator()(date a, date b){
        return a.cost > b.cost;
    }
};

const int inf=1e9;
int n,m,E,x,y,c, flow[620][620], cap[620][620], cost[620][620], ogorder[620][620];
int dist[620], old_dist[620], real_dist[620], inque[620], tata[620];
vector <int> edges[620];
queue <int> q;
priority_queue <date, vector<date>, compare> pq;

void add_edge(int x, int y, int c){
    edges[x].push_back(y);
    edges[y].push_back(x);
    cap[x][y] = 1;
    cost[x][y] += c;
    cost[y][x] -= c;
}

void bellmanford(int source, int sink){
    for(int i=source; i<=sink; i++)
        old_dist[i] = inf;
    old_dist[source] = 0;
    q.push(source);
    while(!q.empty())
    {
        int x = q.front();
        inque[x] = 0;
        q.pop();
        for(auto y:edges[x])
            if(cap[x][y] != 0 and old_dist[x] + cost[x][y] < old_dist[y])
            {
                old_dist[y] = old_dist[x] + cost[x][y];
                if(inque[y] == 0)
                    inque[y] = 1, q.push(y);
            }
    }
}

bool dijkstra(int source, int sink){
    for(int i=source; i<=sink; i++)
        dist[i] = inf;
    dist[source] = 0;
    pq.push({source, 0});
    while(!pq.empty())
    {
        date x = pq.top();
        pq.pop();
        if(x.cost == dist[x.node])
        {
            for(auto y:edges[x.node])
            {
                int new_dist = old_dist[x.node] - old_dist[y] + cost[x.node][y];
                if(flow[x.node][y] < cap[x.node][y] and dist[x.node] + new_dist < dist[y])
                {
                    dist[y] = dist[x.node] + new_dist;
                    real_dist[y] = real_dist[x.node] + cost[x.node][y];
                    tata[y] = x.node;
                    pq.push({y, dist[y]});
                }
            }
        }
    }
    return dist[sink] != inf;
}

int main()
{
    f>>n>>m>>E;
    for(int i=1; i<=E; i++)
    {
        f>>x>>y>>c;
        add_edge(x, n+y, c);
        ogorder[x][n+y] = i;
    }
    for(int i=1; i<=n; i++)
        add_edge(0, i, 0);
    for(int i=1; i<=m; i++)
        add_edge(n+i, n+m+1, 0);
    int totalflow = 0, totalcost = 0;
    bellmanford(0, n+m+1);
    while(dijkstra(0, n+m+1))
    {
        int minim = INT_MAX, sum;
        for(int x=n+m+1; x>0; x=tata[x])
            minim = min(minim, cap[tata[x]][x] - flow[tata[x]][x]);
        totalflow += minim;
        totalcost += minim*real_dist[n+m+1];
        for(int x=n+m+1; x>0; x=tata[x])
        {
            flow[tata[x]][x] += minim;
            flow[x][tata[x]] -= minim;
        }
        for(int i=0; i<=n+m+1; i++)
            old_dist[i] = real_dist[i];
    }
    g<<totalflow<<' '<<totalcost<<'\n';
    for(int x=1; x<=n; x++)
    {
        for(auto y:edges[x])
            if(flow[x][y] == cap[x][y] and y!=0)
            {
                g<<ogorder[x][y]<<' ';
                break;
            }
    }
    return 0;
}