Cod sursa(job #2170471)

Utilizator Tataru_AdelinTataru Adelin Tataru_Adelin Data 15 martie 2018 01:50:40
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.59 kb
#include <bits/stdc++.h>

using namespace std;

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

const int oo = numeric_limits<int>::max();

void Bellman(int source, vector<int>&dist, vector<vector<pair<int,int>>>&path, vector<vector<int>>&flux)
{
    vector<bool>viz(path.size());
    dist[source]=0;

    queue<int>q;
    int now;
    q.push(source);
    viz[source]=1;
    while(!q.empty())
    {
        now=q.front();
        viz[now]=0;
        q.pop();
        for(auto vec:path[now])
        {
            if(flux[now][vec.first]>0 && dist[vec.first]>dist[now]+vec.second)
            {
                dist[vec.first]=dist[now]+vec.second;
                if(!viz[vec.first])
                {
                    q.push(vec.first);
                    viz[vec.first]=1;
                }
            }
        }
    }
}

bool Dijkstra(int source, int dest,vector<int>&dist,vector<vector<pair<int,int>>>&path,vector<vector<int>>&flux,vector<int>&father)
{
    priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>>>q;
    vector<int>dist_d(dist.size(),oo);
    vector<int>dist_u(dist.size(),0);
    vector<bool>viz(dist.size());

    for(unsigned i=0;i<father.size();i++)
        father[i]=0;

    dist_d[source]=dist_u[source]=0;
    int now;
    q.push(make_pair(0,source));
    viz[source]=1;
    while(!q.empty())
    {
        now=q.top().second;
        q.pop();
        viz[now]=0;
        for(auto vec:path[now])
        {
            if(flux[now][vec.first]>0 && dist_d[vec.first]>dist_d[now]+vec.second-dist[now]+dist[vec.first])
            {
                dist_d[vec.first]=dist_d[now]+vec.second-dist[now]+dist[vec.first];
                dist_u[vec.first]=dist_u[now]+vec.second;
                father[vec.first]=now;
                if(!viz[vec.first])
                {
                    viz[vec.first]=1;
                    q.push(make_pair(dist_d[vec.first],vec.first));
                }
            }
        }
    }

    dist=dist_u;

    if(dist_d[dest]!=oo)
        return true;
    else
        return false;
}

void Update(int source, int dest, int &cost, int &flow, vector<int>&dist,vector<int>&father,vector<vector<int>>&flux)
{
    int now;
    for(now=dest;now!=source;now=father[now])
    {
        flux[father[now]][now]--;
        flux[now][father[now]]++;
    }
    flow++;
    cost+=dist[dest];
}

int main()
{
    int card_a,card_b,m;
    fin>>card_a>>card_b>>m;
    vector<vector<pair<int,int>>>path(card_a+card_b+3);
    vector<vector<int>>flux(card_a+card_b+3,vector<int>(card_a+card_b+3));
    vector<pair<int,int>>edges(m+2);

    int x,y,c;
    for(int i=1;i<=m;i++)
    {
        fin>>x>>y>>c;
        edges[i]=make_pair(x,y);
        path[x].push_back(make_pair(y+card_a,c));
        path[y+card_a].push_back(make_pair(x,-c));
        flux[x][y+card_a]=1;
    }

    int source=card_a+card_b+1;
    int dest=source+1;

    for(int i=1;i<=card_a;i++)
    {
        path[source].push_back(make_pair(i,0));
        path[i].push_back(make_pair(source,0));
        flux[source][i]=1;
    }

    for(int i=1;i<=card_b;i++)
    {
        path[dest].push_back(make_pair(i+card_a,0));
        path[i+card_a].push_back(make_pair(dest,0));
        flux[i+card_a][dest]=1;
    }

    vector<int>dist(card_a+card_b+3,oo);
    vector<int>father(card_a+card_b+3,0);

    Bellman(source,dist,path,flux);

    int cost=0,flow=0;

    while(Dijkstra(source,dest,dist,path,flux,father))
        Update(source,dest,cost,flow,dist,father,flux);

    fout<<flow<<' '<<cost<<'\n';

    for(int i=1;i<=m;i++)
    {
        tie(x,y)=edges[i];
        if(flux[x][y+card_a]==0)
            fout<<i<<' ';
    }

    return 0;
}