Cod sursa(job #1521852)

Utilizator Vlad_lsc2008Lungu Vlad Vlad_lsc2008 Data 10 noiembrie 2015 21:41:08
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.7 kb
#include <iostream>
#include <cstdio>
#include <vector>
#include <queue>
#include <cstring>
#define pb push_back
#define nmax 710
#define inf 2000000000
#define min(a,b) ((a)<(b)? (a):(b))
using namespace std;

int st,dr,m1,cost,fin,improve,sol;
int edge[nmax][nmax],c[nmax][nmax],cst[nmax][nmax],d[nmax],tata[nmax],f[nmax][nmax];
bool u[nmax];
vector<int> m[nmax];
queue<int> q;

void build()
{
    int i;
    fin=st+dr;
    fin+=2;
    for(i=2;i<=st+1;i++)
    {
        m[1].pb(i); cst[1][i]=0;
        m[i].pb(1); cst[i][1]=0;
        c[1][i]=1;
    }
    for(i=st+2;i<fin;i++)
    {
        m[i].pb(fin); cst[i][fin]=0;
        m[fin].pb(i); cst[fin][i]=0;
        c[i][fin]=1;
    }
}

int bellman_ford()
{
    int nod,i;
    vector<int>::iterator it;
    memset(u,0,sizeof(u));
    for(i=1;i<=fin;i++) d[i]=inf;
    memset(tata,-1,sizeof(tata));
    d[1]=0; u[1]=1; q.push(1);

    while(!q.empty())
    {
        nod=q.front();
        q.pop();
        u[nod]=false;
        for(it=m[nod].begin();it!=m[nod].end();it++)
        {
            if(c[nod][*it]>f[nod][*it] && d[*it]>d[nod]+cst[nod][*it])
            {
                d[*it]=d[nod]+cst[nod][*it];
                tata[*it]=nod;

                if(!u[*it])
                {
                    q.push(*it);
                    u[*it]=1;
                }
            }
        }
    }

    if(d[fin]<inf)
    {
        int flux=inf;
        for(i=fin;i!=1;i=tata[i])
            flux=min(flux,c[tata[i]][i]-f[tata[i]][i]);
        for(i=fin;i!=1;i=tata[i])
        {
            f[tata[i]][i]+=flux;
            f[i][tata[i]]-=flux;
        }
        return flux*d[fin];
    }

    return 0;
}


int main()
{
    int n1,n2,co,nr=0;
    freopen("cmcm.in","r",stdin);
    freopen("cmcm.out","w",stdout);
    scanf("%d%d%d",&st,&dr,&m1);
    for(int i=1;i<=m1;i++)
    {
        scanf("%d%d%d",&n1,&n2,&co);
        n1++; n2+=st+1;
        m[n1].pb(n2);
        m[n2].pb(n1);
        c[n1][n2]=1;
        edge[n1][n2]=i;
        cst[n1][n2]=co;
        cst[n2][n1]=-co;
    }

    build();

    improve=1;
    while(improve)
    {
        improve=bellman_ford();
        sol+=improve;
    }

    for(int i=2;i<=st+1;i++)
        for(int j=st+2;j<fin;j++)
            if(c[i][j] && f[i][j])
            {
                nr++;
                break;
            }

    printf("%d %d\n", nr, sol);
    for (int i = 2; i <= st + 1; i++)
        for (int j = st + 2; j < fin; j++)
            if (c[i][j] && f[i][j]) {
                printf("%d ", edge[i][j]);
                break;
            }
    printf("\n");

    fclose(stdin);
    fclose(stdout);
    return 0;
}