Cod sursa(job #1280469)

Utilizator bogdanpaunFMI Paun Bogdan Gabriel bogdanpaun Data 1 decembrie 2014 23:25:48
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.47 kb
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <queue>
using namespace std;
#define N 700

vector< pair<int,int> > v[N];
vector< pair<int,int> >::iterator it , endd;
int n , m , x , y , z , muchii , fin  , i,j , improve   ;
int cap[N][N],flux[N][N];
int muchie[N][N];
int dist[N],ant[N];
bool use[N];

int bellman_ford(){
    for(i=1;i<=fin;++i){
        ant[i] = -1;
        use[i] = 0;
        dist[i] = 1<<29;
    }
    queue<int> q; dist[1] = 0; use[1] = true;
    for(q.push(1);  !q.empty() ; q.pop() ){
        x = q.front();
        for(it = v[x].begin() ; it != v[x].end() ; ++it ){
            y = it->first;
            if( cap[x][y] <= flux[x][y] || (dist[x] + it->second) >= dist[y]   ) continue;
            dist[y] = dist[x] + it->second;  ant[y] = x;
            if(!use[y]){
                q.push(y);
                use[y] = true;
            }
        }
        use[x] = false;
    }
    if( dist[ fin ] < (1<<29) ){
        int ff = 1<<30;
        for(i=fin; i != 1; i = ant[i] )
            ff = min(ff , cap[ant[i] ][i] - flux[ant[i] ][i]);
        if( ff != 0 )
         for(i=fin; i != 1; i = ant[i] ){
            flux[ant[i] ][i] += ff;
            flux[i][ant[i] ] -= ff;
         }
         return ff * dist[fin];
    }
    return 0;
}

int main()
{
    freopen("cmcm.in"  ,"r" ,stdin  );
    freopen("cmcm.out" ,"w" ,stdout );
    scanf("%d %d %d\n",&n,&m,&muchii);
    for(i = 1 ; i <= muchii ; ++i){
        scanf("%d %d %d\n",&x,&y,&z);
        ++x; y+= n+1;
        v[x].push_back( {y , z} );
        v[y].push_back( {x ,-z} );
        cap[x][y] = 1;
        muchie[x][y] = i;
    }

    fin = n + m + 2;

    for(i = 2; i <= n+1; ++i){
        v[1].push_back( {i,0} );
        v[i].push_back( {1,0} );
        cap[1][i] = 1;
    }

    for(i = n+2; i <= fin-1; ++i){
        v[fin].push_back( {i  ,0} );
        v[i  ].push_back( {fin,0} );
        cap[i][fin] = 1;
    }
    z = 0;
    int sol=0; improve = 1;
    for( ; improve ;  ){
        improve = bellman_ford();
        sol += improve;
    }
    queue<int> lista;
    for(i = 2; i <= n+1 ; ++i)
        for(j=n+2; j < fin; ++j)
            if( cap[i][j] && flux[i][j] ){
                    lista.push(muchie[i][j]);
                    break;
            }
    printf("%d %d\n",lista.size(),sol);
    for( ;!lista.empty() ; lista.pop() ){
        printf("%d ",lista.front() );
    }


    return 0;
}