Cod sursa(job #554988)

Utilizator feelshiftFeelshift feelshift Data 15 martie 2011 10:56:47
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.61 kb
// http://infoarena.ro/problema/cmcm
#include <fstream>
#include <cstring>
#include <map>
#include <vector>
#include <queue>
using namespace std;

const int maxSize = 611;
const int oo = 0x3f3f3f3f;
const int source = 0;
const int sink = 610;

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

int firstSize,secondSize,edges;
bool visit[maxSize];
int father[maxSize];
int dist[maxSize];
//int edge[maxSize][maxSize];
int cost[maxSize][maxSize];
int capacity[maxSize][maxSize];
int currentFlow[maxSize][maxSize];
map< pair<int,int>, int> EDGE;
vector<int> graph[maxSize];

bool bellmanFord();

int main() {
    in >> firstSize >> secondSize >> edges;

    int from,to,currentCost;
    for(int i=1;i<=edges;i++) {
        in >> from >> to >> currentCost;
        to += firstSize;

        graph[from].push_back(to);
        graph[to].push_back(from);

        cost[from][to] = currentCost;
        cost[to][from] = -currentCost;

        capacity[from][to] = 1;
        //edge[from][to] = i;
        EDGE[make_pair(from,to)] = i;
    }

    for(int i=1;i<=firstSize;i++) {
        graph[source].push_back(i);
        graph[i].push_back(source);
        capacity[source][i] = 1;
    }

    for(int i=firstSize+1;i<=firstSize+secondSize;i++) {
        graph[i].push_back(sink);
        graph[sink].push_back(i);
        capacity[i][sink] = 1;
    }

    int maxFlow = 0;
    while(bellmanFord()) {
        int minFlow = oo;
        for(int node=sink;node!=source;node=father[node])
            minFlow = min(minFlow,capacity[father[node]][node] - currentFlow[father[node]][node]);

        for(int node=sink;node!=source;node=father[node]) {
            currentFlow[father[node]][node] += minFlow;
            currentFlow[node][father[node]] -= minFlow;
        }

        maxFlow += minFlow * dist[sink];
    }

    int tmp = 0;
    /*for(int f=1;f<=firstSize;f++)
        for(int s=firstSize+1;s<=firstSize+secondSize;s++)
            if(capacity[f][s] && currentFlow[f][s])
                tmp++;*/
    map< pair<int,int>, int>::iterator it,end;
    end = EDGE.end();
    for(it=EDGE.begin();it!=end;++it)
        if(capacity[it->first.first][it->first.second] && currentFlow[it->first.first][it->first.second])
            tmp++;

    out << tmp << " " << maxFlow << "\n";

    /*for(int f=1;f<=firstSize;f++)
        for(int s=firstSize+1;s<=firstSize+secondSize;s++)
            if(capacity[f][s] && currentFlow[f][s]) {
                out << edge[f][s] << " ";
            }*/
    for(it=EDGE.begin();it!=end;++it)
        if(capacity[it->first.first][it->first.second] && currentFlow[it->first.first][it->first.second])
            out << it->second << " ";
    out << "\n";

    in.close();
    out.close();

    return (0);
}

bool bellmanFord() {
    memset(visit,false,sizeof(visit));
    visit[source] = true;

    memset(dist,oo,sizeof(dist));
    dist[source] = 0;

    int node;
    vector<int>::iterator it,end;

    queue<int> myQueue;
    myQueue.push(source);

    while(!myQueue.empty()) {
        node = myQueue.front();
        myQueue.pop();

        end = graph[node].end();
        for(it=graph[node].begin();it!=end;++it)
            if(capacity[node][*it] > currentFlow[node][*it] && dist[*it] > dist[node] + cost[node][*it]) {
                dist[*it] = dist[node] + cost[node][*it];
                father[*it] = node;

                if(!visit[*it]) {
                    myQueue.push(*it);
                    visit[*it] = true;
                }
            }

        visit[node] = false;
    }

    return (dist[sink] != oo);
}