Cod sursa(job #1518031)

Utilizator StarGold2Emanuel Nrx StarGold2 Data 5 noiembrie 2015 10:55:40
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.74 kb
#include <cstdio>
#include <queue>
#include <vector>
#include <algorithm>
#include <bitset>

#define DIM 1024
#define node1 first
#define node2 second
#define INF 1000000000
using namespace std;

int startNode, finishNode, nrEdges;
int nrNodes1, nrNodes2, node1, node2;

int Distance[DIM], Capacity[DIM][DIM];
int Cost[DIM][DIM], MaxFlow[DIM][DIM];
bitset <DIM> Marked; queue <int> Queue;
vector <int> Edges[DIM]; int Father[DIM];
pair <int , int> SolEdges[DIM*100]; int cost;

bool bellmanFord (int startNode, int finishNode)
{
    while (!Queue.empty()) Queue.pop();
    Marked.reset(); Marked[startNode] = 1;
    Queue.push(startNode);

    for (int i = 0; i <= finishNode; i ++)
        Distance[i] = INF;
    Distance[startNode] = 0;

    int ok = 0;
    while (!Queue.empty())
    {
        int node = Queue.front();

        vector <int> :: iterator it;
        for (it = Edges[node].begin(); it != Edges[node].end(); it ++)
        {
            int nextNode = *it;

            if (MaxFlow[node][nextNode] < Capacity[node][nextNode])
            if (Distance[nextNode] > Distance[node] + Cost[node][nextNode])
            {
                Distance[nextNode] = Distance[node] + Cost[node][nextNode];
                Father[nextNode] = node;

                if (!Marked[nextNode])
                {
                    Marked[nextNode] = 1;
                    Queue.push(nextNode);

                    if (nextNode == finishNode)
                        ok = 1;
                }
            }
        }

        Marked[node] = 0;
        Queue.pop();
    }

    return ok;
}

int main ()
{
    freopen ("cmcm.in" ,"r", stdin );
    freopen ("cmcm.out","w", stdout);

    scanf ("%d %d %d", &nrNodes1, &nrNodes2, &nrEdges);
    startNode = 0; finishNode = nrNodes1 + nrNodes2 + 1;

    for (int i = 1; i <= nrEdges; i ++)
    {
        scanf ("%d %d %d", &node1, &node2, &cost);
        node2 += nrNodes1;

        Capacity[node1][node2] = 1;
        Capacity[node2][node1] = 0;
        Cost[node1][node2] =  cost;
        Cost[node2][node1] = -cost;

        Edges[node1].push_back(node2);
        Edges[node2].push_back(node1);

        SolEdges[i].node1 = node1;
        SolEdges[i].node2 = node2;
    }

    for (int i = 1; i <= nrNodes1; i ++)
    {
        Capacity[startNode][i] = 1;
        Capacity[i][startNode] = 0;
        Cost[startNode][i] = 0;
        Cost[i][startNode] = 0;

        Edges[startNode].push_back(i);
        Edges[i].push_back(startNode);
    }

    for (int i = 1; i <= nrNodes2; i ++)
    {
        i += nrNodes1;

        Capacity[i][finishNode] = 1;
        Capacity[finishNode][i] = 0;
        Cost[i][finishNode] = 0;
        Cost[finishNode][i] = 0;

        Edges[i].push_back(finishNode);
        Edges[finishNode].push_back(i);

        i -= nrNodes1;
    }

    int flow = 0, cost = 0;
    while (bellmanFord(startNode, finishNode))
    {
        int minim = INF;

        for (int node = finishNode; node != startNode; node = Father[node])
            minim = min (minim, Capacity[Father[node]][node] - MaxFlow[Father[node]][node]);

        flow += minim;

        for (int node = finishNode; node != startNode; node = Father[node])
        {
            MaxFlow[Father[node]][node] += minim;
            MaxFlow[node][Father[node]] -= minim;

            cost += minim * Cost[Father[node]][node];
        }
    }

    printf ("%d %d\n", flow, cost);

    for (int i = 1; i <= nrEdges; i ++)
    {
        node1 = SolEdges[i].node1;
        node2 = SolEdges[i].node2;

        if (MaxFlow[node1][node2] == Capacity[node1][node2])
            printf ("%d ", i);
    }

    fclose (stdin );
    fclose (stdout);

    return 0;
}