Cod sursa(job #2715089)

Utilizator adiaioanaAdia R. adiaioana Data 2 martie 2021 22:56:27
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.26 kb
#include <fstream>
#include <vector>
#include <queue>
#include <set>
#define LL long long
using namespace std;
ifstream cin("cmcm.in");
ofstream cout("cmcm.out");

int viz[700], ant[700];
LL fl[700][700];
LL inf=1000000000;
int N,M, S,E,mm[50500], D,idm[700][700];
LL Fm,Fcst;
LL d[700], old_d[700], real_d[700], Cst[700][700];

vector <int> G[700];
vector <pair<int,int> > linii;
queue <int> Q;
priority_queue <pair<LL,int>, vector <pair<LL,int> >, greater < pair<LL,int> > > pq;

inline void scan();
inline void fordfiesta();
bool daicstra();
int id(int x,int y)
{
    if(x<y)
        return idm[x][y];
    else return idm[y][x];
}
/// bruno mars e overrated
int main()
{
    scan();
    fordfiesta();

    while(daicstra());
    cout<<Fm<<' '<<Fcst<<'\n';
    for(int i=1; i<=E; ++i)
        if(mm[i]==0)
            cout<<i<<' ';
    cout<<'\n';
    return 0;
}

inline void scan()
{
    int x,y,c;
    cin>>N>>M>>E;
    for(int i=1; i<=E; ++i)
    {
        cin>>x>>y>>c;
        mm[i]=1;
        y+=N;
        idm[x][y]=i;

        G[x].push_back(y);
        G[y].push_back(x);
        fl[x][y]=1;
        Cst[x][y]=c;
        Cst[y][x]=-c;
    }

    S=0; D=N+M+1;
    for(int i=1; i<=N; ++i)
    {
        fl[0][i]=1;
        G[0].push_back(i);
        G[i].push_back(0);
    }

    for(int i=N+1; i<=N+M; ++i)
    {
        fl[i][N+M+1]=1;
        G[N+M+1].push_back(i);
        G[i].push_back(N+M+1);
    }
}

inline void fordfiesta()
{
    int nod;
    LL new_d;
    for(int i=S; i<=D; ++i) old_d[i]=inf;
    viz[S]=1;
    old_d[S]=0;
    Q.push(S);
    while(!Q.empty())
    {
        nod=Q.front();
        Q.pop();
        viz[nod]=0;
        if(nod==D)
            continue;

        for(auto nn:G[nod])
            if(fl[nod][nn])
        {
            new_d=old_d[nod]+Cst[nod][nn];
            if(new_d<old_d[nn])
            {
                old_d[nn]=new_d;
                if(!viz[nn])
                {
                    viz[nn]=1;
                    Q.push(nn);
                }
            }
        }
    }
}

bool daicstra()
{
    int nod; LL cost, new_d;
    for(int i=S; i<=D; ++i)
        d[i]=inf;
    real_d[S]=d[S]=0;
    pq.push({0,S});
    while(!pq.empty())
    {
        nod=pq.top().second;
        cost=pq.top().first;
        pq.pop();
        if(cost!=d[nod])
            continue;
        for(auto nn:G[nod])
            if(fl[nod][nn])
        {
            new_d=d[nod]+old_d[nod]-old_d[nn]+Cst[nod][nn];
            if(new_d<d[nn])
            {
                d[nn]=new_d;
                real_d[nn]=real_d[nod]+Cst[nod][nn];
                ant[nn]=nod;
                pq.push({d[nn],nn});
            }
        }
    }
    if(d[D]==inf)
        return 0;
    for(int i=S; i<=D; ++i) old_d[i]=real_d[i];

    long long Fmin=inf, total=0;
    for(nod=D; nod!=S; nod=ant[nod])
    {
        Fmin=min(Fmin, 1ll*fl[ant[nod]][nod]);
        total+=Cst[ant[nod]][nod];
    }
    Fm+=Fmin;
    Fcst+=(Fmin*total);
    for(nod=D; nod!=S; nod=ant[nod])
    {
        if(ant[nod]!=S && nod!=D)
        mm[id(ant[nod],nod)]=1-mm[id(ant[nod],nod)];
        fl[ant[nod]][nod]-=Fmin;
        fl[nod][ant[nod]]+=Fmin;
    }
    return 1;
}