Cod sursa(job #1120181)

Utilizator alexalghisiAlghisi Alessandro Paolo alexalghisi Data 24 februarie 2014 21:59:27
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.81 kb
#include <iostream>
#include <fstream>
#include <algorithm>
#include <bitset>
#include <cstdio>
#include <vector>
#include <cmath>
#include <queue>
#include <string>
#include <map>
#include <set>


#define DN 713
#define pb push_back
#define mp make_pair
#define per pair<int,int>
#define INF (1<<30)
#define LL long long
#define un unsigned
#define x first
#define y second
#define next_nod list[nod][i]
using namespace std;

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

vector<int> list[DN];
queue<int> q;
bitset< DN > in_q;

int cost[DN][DN],C[DN][DN],F[DN][DN],n,m,e,edge[DN][DN],rez,prec[DN],d[DN];
int S,D,exista_drum;

void read(){

    f>>n>>m>>e;
    for(int i = 1;i<=e;++i){

        int a,b,z;
        f>>a>>b>>z;
        ++a;
        b += ( n + 1 ) ; /// nodurile din dreapta
        list[a].pb(b);
        list[b].pb(a);

        cost[a][b] = z;
        cost[b][a] = -z;
        C[a][b] = 1;
        edge[a][b]=i;
    }
}

void build_graph(){

    S = 1;
    D = n + m + 2;
    for(int i=1;i<=n+1;++i){
        list[S].pb(i);
        list[i].pb(S);
        cost[S][i] = 0;
        cost[i][S] = 0;
        C[S][i] = 1;
    }
    for(int i=n+2;i <= n + m + 1; ++i){
        list[D].pb(i);
        list[i].pb(D);
        cost[D][i] = 0;
        cost[i][D] = 0;
        C[i][D] = 1;
    }
}

int bf(){

    for(int i=1;i<=n+m+2;++i){
        d[i]=INF;
        prec[i]=-1;
    }

    d[S] = 0 ;
    q.push(S);
    in_q[S]=true;

    for(; q.size() ; ){

        int nod = q.front();
        q.pop();
        in_q[nod] = false;

        for(int i=0;i<list[nod].size();++i){

            if(C[nod][next_nod] - F[nod][next_nod] > 0 && d[next_nod] > d[nod] + cost[nod][next_nod] ){

                d[next_nod] = d[nod] + cost[nod][next_nod];
                prec[next_nod] = nod;
                if(!in_q[next_nod]){

                    q.push(next_nod);
                    in_q[next_nod] = true;
                }
            }
        }
    }
    if(d[D]!=INF){

        exista_drum = true;
        int vmin = INF;

        for(int nod = D ; nod!=S ; nod = prec[nod])
            vmin=min(vmin,C[ prec[nod] ][ nod ] - F[ prec[nod] ][ nod ]);
        for(int nod = D ; nod!=S ; nod = prec[nod]){

            F[prec[nod]][nod]+=vmin;
            F[nod][prec[nod]]-=vmin;
        }
        return vmin*d[D];
    }
    return 0;
}

void solve(){

    exista_drum = 1;
    for( ; exista_drum ; ){

        exista_drum = 0;
        rez += bf();
    }
}

void print(){

    int nr=0;
    for(int i=2;i<=n+1;++i)
        for(int j=n+2;j<=n+m+1;++j)
            if(C[i][j] && F[i][j]){
                ++nr;
            }
    g<<nr<<" "<<rez<<"\n";
    for(int i=2;i<=n+1;++i)
        for(int j=n+2;j<=n+m+1;++j)
            if(C[i][j] && F[i][j])
                g<<edge[i][j]<<" ";
}

int main()
{
    read();
    build_graph();
    solve();
    print();

    return 0;
}