Cod sursa(job #2271758)

Utilizator Dobricean_IoanDobricean Ionut Dobricean_Ioan Data 29 octombrie 2018 10:44:05
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.39 kb
#include <cstdio>
#include <vector>
#include <algorithm>
 
#define MAXN 602
#define INF 0x3f3f3f3f
 
using namespace std;
 
vector <int> G[MAXN];
 
int dad[MAXN], q[MAXN*MAXN], flow[MAXN][MAXN], capacity[MAXN][MAXN], cost[MAXN][MAXN], dist[MAXN], idx[MAXN][MAXN];
int maxflow, mincost, edges, n, m, source, sink;
bool inq[MAXN];
 inline bool bellmanford();

 
int main()
{
    freopen("cmcm.in", "r", stdin);
    freopen("cmcm.out", "w", stdout);
 
    int i, x, y, c, j;
 
    scanf("%d%d%d", &n, &m, &edges);
 
    for(i=1; i<=edges; ++i)
    {
        scanf("%d%d%d", &x, &y, &c);
        y += n;
 
        capacity[x][y] = 1;
        cost[x][y] = c;
        cost[y][x] = -c;
        idx[x][y] = i;
 
        G[x].push_back(y);
        G[y].push_back(x);
    }
 
    for(i=1; i<=n; ++i)
    {
        G[0].push_back(i);
        capacity[0][i] = 1;
        cost[0][i] = 0;
    }
 
    for(i=n+1; i<=n+m; ++i)
    {
        G[i].push_back(n+m+1);
        capacity[i][n+m+1] = 1;
    }
 
    source = 0;
    sink = n+m+1;
 
    for(; bellmanford(); );
 
    printf("%d %d\n", maxflow, mincost);
 
    for(i=1; i<=n; ++i)
        for(j=n+1; j<=n+m; ++j)
            if(flow[i][j] > 0)
                printf("%d ", idx[i][j]);
 
    return 0;
}

inline bool bellmanford()
{
    int node, left, right, i, minflow, son;
 
    for(i=0; i<=n+m+1; ++i)
        dist[i] = INF;
 
    dist[source] = 0;
    left = right = 0;
    q[right++] = source;
    inq[source] = 1;
 
    while(left < right)
    {
        node = q[left++];
        inq[node] = 0;
 
        if(node == sink) continue;
 
        for(i=0; i<G[node].size(); ++i)
        {
            son = G[node][i];
            if(flow[node][son] < capacity[node][son] && dist[node] + cost[node][son] < dist[son])
            {
                dist[son] = dist[node] + cost[node][son];
                dad[son] = node;
                if(!inq[son])
                {
                    inq[son] = 1;
                    q[right++] = son;
                }
            }
        }
    }
 
    if(dist[sink] == INF) return 0;
 
    minflow = INF;
    for(node=sink; node!=source; node=dad[node])
        minflow = min(minflow, capacity[dad[node]][node] - flow[dad[node]][node]);
 
    for(node=sink; node!=source; node=dad[node])
    {
        flow[dad[node]][node] += minflow;
        flow[node][dad[node]] -= minflow;
    }
 
    maxflow += minflow;
    mincost += minflow * dist[sink];
 
    return 1;
}