Cod sursa(job #1970136)

Utilizator caprariuapCaprariu Alin-Paul caprariuap Data 18 aprilie 2017 22:11:20
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.5 kb
#include <fstream>
#include <cstring>
#include <vector>
#include <algorithm>
#include <stack>
#include <iomanip>
#include <queue>
using namespace std;

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

#define nmax 610
vector <int> v[nmax];
int n,m,e,i,c[nmax][nmax],f[nmax][nmax],p[nmax],maxflow,maxcost,S,D,oldd[nmax],d[nmax],reald[nmax],cost[nmax][nmax],edge[nmax][nmax];
bool use[nmax];

void bellmanford()
{
    queue <int> Q;
    bool inQ[nmax];
    for (i=1; i<=n; i++)
        inQ[i]=0,oldd[i]=20000000;
    Q.push(S);
    inQ[S]=1;
    oldd[S]=0;
    while (!Q.empty())
    {
        int nod=Q.front();
        Q.pop();
        inQ[nod]=0;
        for (int i=0; i<v[nod].size(); i++)
        {
            int vecin=v[nod][i];
            if (c[nod][vecin]&&oldd[nod]+cost[nod][vecin]<oldd[vecin])
            {
                oldd[vecin]=oldd[nod]+cost[nod][vecin];
                if (inQ[vecin]==0)
                    Q.push(vecin),inQ[vecin]=1;
            }
        }
    }
}

bool dijkstra()
{
    priority_queue <pair <int, int>, vector <pair <int, int> >, greater<pair <int, int> > > H;
    for (i=1; i<=n; i++)
        d[i]=20000000,p[i]=-1;
    d[S]=0;
    reald[S]=0;
    H.push(make_pair(d[S],S));
    while (!H.empty())
    {
        int nod=H.top().second,cc=H.top().first;
        H.pop();
        if (cc>d[nod])
            continue;
        for (int i=0; i<v[nod].size(); i++)
        {
            int vecin=v[nod][i];
            if (c[nod][vecin]>f[nod][vecin])
            {
                int aux=cost[nod][vecin]+oldd[nod]-oldd[vecin];
                if (cc+aux<d[vecin])
                {
                    d[vecin]=cc+aux;
                    p[vecin]=nod;
                    reald[vecin]=reald[nod]+cost[nod][vecin];
                    H.push(make_pair(d[vecin],vecin));
                }
            }
        }
    }
    if (p[D]==-1)
        return 0;
    int fmin=4000000;
    for (int nod=D; nod!=S; nod=p[nod])
        fmin=min(fmin,c[p[nod]][nod]-f[p[nod]][nod]);
    for (int nod=D; nod!=S; nod=p[nod])
    {
        f[p[nod]][nod]+=fmin;
        f[nod][p[nod]]-=fmin;
    }
    maxflow+=fmin;
    maxcost=maxcost+fmin*reald[D];
    for (i=1; i<=n; i++)
        oldd[i]=reald[i];
    return 1;
}

int main()
{
    fin >> n >> m >> e;
    for (i=1; i<=e; i++)
    {
        int A,B,C;
        fin >> A >> B >> C;
        A+=1;
        B+=n+1;
        v[A].push_back(B);
        v[B].push_back(A);
        cost[A][B]=C;
        cost[B][A]=-C;
        c[A][B]=1;
        edge[A][B]=i;
    }
    S=1;
    int aux=n;
    n=n+m+2;
    m=aux;
    D=n;
    for (i=2; i<=m+1; i++)
    {
        int A,B;
        A=S;
        B=i;
        v[A].push_back(B);
        v[B].push_back(A);
        cost[A][B]=0;
        cost[B][A]=0;
        c[A][B]=1;
    }
    for (i=m+2; i<=n-1; i++)
    {
        int A,B;
        A=i;
        B=D;
        v[A].push_back(B);
        v[B].push_back(A);
        cost[A][B]=0;
        cost[B][A]=0;
        c[A][B]=1;
    }
    bellmanford();
    maxflow=maxcost=0;
    int nr=0;
    while (dijkstra());
    for (i=2; i<=m+1; i++)
        for (int j=m+2; j<=n-1; j++)
            if (c[i][j]&&f[i][j])
                nr++;
    fout << nr << ' ' << maxcost << '\n';
    for (i=2; i<=m+1; i++)
        for (int j=m+2; j<=n-1; j++)
            if (c[i][j]&&f[i][j])
            {
                fout << edge[i][j] << ' ';
                break;
            }
}