Cod sursa(job #2628819)

Utilizator betybety bety bety Data 17 iunie 2020 17:06:12
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.99 kb
#include <fstream>
#include <vector>
#include <queue>
using namespace std;
ifstream cin("cmcm.in");
ofstream cout("cmcm.out");
vector<pair<int,int> > vec[606];
vector<pair<int,int> > edge;
const int inf=1e9+7;
int c[606][606];
int pred[606];
int dist[606];
bool inq[606];
queue<int> q;
int main()
{
    int n,m,e,x,y,z;
    cin>>n>>m>>e;
    edge.push_back({0,0});
    for(int i=1;i<=e;++i)
    {
        cin>>x>>y>>z;
        edge.push_back({x,y});
        vec[x].push_back({n+y,z});
        vec[n+y].push_back({x,-z});
        c[x][n+y]=1;
    }
    for(int i=1;i<=n;++i)
    {
        vec[0].push_back({i,0});
        vec[i].push_back({0,0});
        c[0][i]=1;
    }
    for(int i=n+1;i<=n+m;++i)
    {
        vec[i].push_back({n+m+1,0});
        vec[n+m+1].push_back({i,0});
        c[i][n+m+1]=1;
    }
    int flow=0,cost=0,ads;
    do
    {
        for(int i=1;i<=n+m+1;++i)
        {
            pred[i]=-1;
            dist[i]=inf;
        }
        pred[0]=-2;
        dist[0]=0;
        q.push(0);
        inq[0]=true;
        while(!q.empty())
        {
            int x=q.front(); q.pop();
            inq[x]=false;
            for(auto y:vec[x])
            if(c[x][y.first]>0 and dist[y.first]>dist[x]+y.second)
            {
                dist[y.first]=dist[x]+y.second;
                pred[y.first]=x;
                if(!inq[y.first]) inq[y.first]=true,q.push(y.first);
            }
        }
        if(pred[n+m+1]>=0)
        {
            ads=inf;
            for(int k=n+m+1;pred[k]>=0;k=pred[k])
                ads=min(ads,c[pred[k]][k]);
            for(int k=n+m+1;pred[k]>=0;k=pred[k])
            {
                c[pred[k]][k]-=ads;
                c[k][pred[k]]+=ads;
            }
            flow+=ads;
            cost+=ads*dist[n+m+1];
        }
    }while(pred[n+m+1]>=0);
    cout<<flow<<' '<<cost<<'\n';
    for(int i=1;i<=e;++i)
    if(!c[edge[i].first][edge[i].second+n])
        cout<<i<<' ';
    return 0;
}