Cod sursa(job #833053)

Utilizator alex_unixPetenchea Alexandru alex_unix Data 11 decembrie 2012 20:45:16
Problema Cuplaj maxim de cost minim Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 3.32 kb

#include <cstdio>
#include <cstring>
 
const int MAX_SIZE(602);
const int MAX_COST(1 << 30);
 
int vertices, source, sink, l, r, e, maxflow, min_cost;
 
int capacity [MAX_SIZE] [MAX_SIZE];
int cost [MAX_SIZE] [MAX_SIZE];
int min_path [MAX_SIZE];
int queue [MAX_SIZE * MAX_SIZE], *pop, *push;
int pred [MAX_SIZE];
bool in_queue [MAX_SIZE];
int edges [MAX_SIZE] [MAX_SIZE];
 
struct edge
{
    int node;
    struct edge *next;
} *graph [MAX_SIZE];
 
inline void add (int x, int y)
{
    struct edge *new_edge(new struct edge);
    new_edge->node = y;
    new_edge->next = graph[x];
    graph[x] = new_edge;
}
 
inline void read (void)
{
    std::freopen("cmcm.in","r",stdin);
    std::scanf("%d %d %d",&l,&r,&e);
    vertices = l + r;
    source = 0;
    sink = vertices + 1;
    int x, y, c;
    for (int counter(1) ; counter <= e ; ++counter)
    {
        std::scanf("%d %d %d",&x,&y,&c);
        y += l;
        add(x,y);
        add(y,x);
        edges[x][y] = counter;
        cost[x][y] = c;
        cost[y][x] = -c;
        capacity[x][y] = 1;
        add(source,x);
        add(y,sink);
        capacity[source][x] = 1;
        capacity[y][sink] = 1;
    }
    std::fclose(stdin);
}
 
inline void initialize (void)
{
    std::memset(pred,0,sizeof(*pred) * (sink + 1));
    std::memset(in_queue,0,sizeof(*in_queue) * (sink + 1));
    for (int index(source) ; index <= sink ; ++index)
        min_path[index] = MAX_COST;
    in_queue[source] = true;
    min_path[source] = 0;
    *queue = source;
    pop = queue;
    push = queue + 1;
}
 
inline void BellmanFord (void)
{
    initialize();
    int vertex, neighbor;
    struct edge *iterator;
    while (pop < push)
    {
        vertex = *pop;
        ++pop;
        for (iterator = graph[vertex] ; iterator ; iterator = iterator->next)
            if (capacity[vertex][iterator->node] && min_path[vertex] + cost[vertex][iterator->node] < min_path[iterator->node])
            {
                neighbor = iterator->node;
                min_path[neighbor] = min_path[vertex] + cost[vertex][neighbor];
                pred[neighbor] = vertex;
                if (!in_queue[neighbor])
                {
                    *push = neighbor;
                    ++push;
                    in_queue[neighbor] = true;
                }
            }
        in_queue[vertex] = false;
    }
}
 
inline void FordFulkerson (void)
{
    int vertex;
    while (true)
    {
        BellmanFord();
        if (!pred[sink])
            break;
        for (vertex = sink ; vertex != source ; vertex = pred[vertex])
        {
            capacity[pred[vertex]][vertex] = 0;
            capacity[vertex][pred[vertex]] = 1;
        }
        min_cost += min_path[sink];
        ++maxflow;
    }
}
 
inline void print (void)
{
    std::freopen("cmcm.out","w",stdout);
    int i, j;
    std::printf("%d %d\n",maxflow,min_cost);
    for (i = 1 ; i <= l ; ++i)
        for (j = l + 1 ; j <= vertices ; ++j)
            if (edges[i][j])
                if (!capacity[i][j])
                {
                    std::printf("%d ",edges[i][j]);
                    break;
                }
    std::putchar('\n');
    std::fclose(stdout);
}
 
int main (void)
{
    read();
    FordFulkerson();
    print();
    return 0;
}