Cod sursa(job #1402859)

Utilizator maribMarilena Bescuca marib Data 26 martie 2015 21:34:05
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.97 kb
#include <fstream>
#include <cstring>
#include <vector>
#include <queue>
#define DIM 605
#define INF 0x3f3f3f
#define minim(a, b) ((a)<(b)?a:b)

using namespace std;

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

struct edge{
    int price, dest;
};

edge temp;

vector <edge> edges[DIM];

int l, r, cap[DIM][DIM], flow[DIM][DIM], ind_edge[DIM][DIM], m;

void build_graph(){

    for(int i=1; i<=l; ++i){

        temp.dest=i;
        temp.price=0;
        cap[0][i]=1;
        edges[0].push_back(temp);
        temp.dest=0;
        edges[i].push_back(temp);

    }

    for(int i=l+1; i<=l+r; ++i){

        temp.dest=l+r+1;
        temp.price=0;
        cap[i][l+r+1]=1;
        edges[i].push_back(temp);
        temp.dest=i;
        edges[l+r+1].push_back(temp);

    }

}

int bellman_ford(){

    int source=0, added[DIM], best[DIM], vfc, neigh, trace[DIM], flow_to_add;
    queue <int> q;
    long long step=0;

    memset(added, 0, sizeof(added));
    memset(best, INF, sizeof(best));
    memset(trace, 0, sizeof(trace));

    q.push(source);
    best[source]=0;
    added[source]=1;

    while(!q.empty()&&step<=1LL*(l+r+1)*2*m){

        vfc=q.front();
        q.pop();

        for(int i=0; i<edges[vfc].size(); ++i){

            neigh=edges[vfc][i].dest;
            if(cap[vfc][neigh]>flow[vfc][neigh]&&best[neigh]>best[vfc]+edges[vfc][i].price){
                best[neigh]=best[vfc]+edges[vfc][i].price;
                trace[neigh]=vfc;
                if(!added[neigh]){
                    added[neigh]=1;
                    q.push(neigh);
                }
            }

        }

        added[vfc]=0;

    }

    if(best[l+r+1]<INF){

        flow_to_add=INF;

        vfc=l+r+1;
        while(vfc!=0){

            flow_to_add=minim(flow_to_add, cap[trace[vfc]][vfc]-flow[trace[vfc]][vfc]);
            vfc=trace[vfc];

        }

        vfc=l+r+1;
        while(vfc!=0){

            flow[trace[vfc]][vfc]+=flow_to_add;
            flow[vfc][trace[vfc]]-=flow_to_add;
            vfc=trace[vfc];
        }

        return flow_to_add*best[l+r+1];

    }

    return 0;

}

void cmcm(){

    int better=1, res=0, number=0;

    while(better){
        better=bellman_ford();
        res+=better;
    }

    for(int i=1; i<=l; ++i){
        for(int j=l+1; j<=l+r; ++j){
            if(cap[i][j]&&flow[i][j]){
                number++;
                break;
            }
        }
    }

    out<<number<<" "<<res<<"\n";

    for(int i=1; i<=l; ++i){
        for(int j=l+1; j<=l+r; ++j){
            if(cap[i][j]&&flow[i][j])
                out<<ind_edge[i][j]<<" ";
        }
    }

    out<<"\n";
}

int main()
{
    int a, b, c, x;

    in>>l>>r>>m;

    x=0;

    while(x<m){
        in>>a>>b>>c;
        b+=l;

        temp.dest=b; temp.price=c;
        edges[a].push_back(temp);

        temp.price=-c; temp.dest=a;
        edges[b].push_back(temp);

        cap[a][b]=1;
        x++;
        ind_edge[a][b]=x;
    }

    build_graph();

    cmcm();

    in.close();
    out.close();
    return 0;
}