Cod sursa(job #1543094)

Utilizator fanache99Constantin-Buliga Stefan fanache99 Data 5 decembrie 2015 22:20:24
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.55 kb
#include<cstdio>
#include<vector>
#include<queue>
#define inf 2000000000
using namespace std;
vector<int> g[610];
int flow[610][610],capacity[610][610],cost[610][610],n,s,d,old[610],real[610],best[610],in_queue[610],dad[610],index[610][610];
queue<int> q;
struct node{
    int index,cost;
    const bool operator < (const node&b) const{
        return this->cost>b.cost;
    }
};
node temp;
priority_queue<node> h;
int minim(int a,int b){
    if(a<b)
        return a;
    return b;
}
void bellman_ford(){
    int i,dim,node;
    for(i=0;i<=n+1;i++)
        old[i]=inf;
    old[s]=0;
    q.push(s);
    in_queue[s]=1;
    while(!q.empty()){
        node=q.front();
        q.pop();
        in_queue[node]=0;
        dim=g[node].size();
        for(i=0;i<dim;i++){
            if(capacity[node][g[node][i]]==flow[node][g[node][i]])
                continue;
            if(old[g[node][i]]>old[node]+cost[node][g[node][i]]){
                old[g[node][i]]=old[node]+cost[node][g[node][i]];
                if(in_queue[g[node][i]]==0){
                    in_queue[g[node][i]]=1;
                    q.push(g[node][i]);
                }
            }
        }
    }
}
int dijkstra(){
    int i,dim,node,current,distance;
    for(i=0;i<=n+1;i++)
        best[i]=inf;
    best[s]=real[s]=0;
    temp.index=s;
    temp.cost=0;
    h.push(temp);
    while(!h.empty()){
        node=h.top().index;
        current=h.top().cost;
        dim=g[node].size();
        h.pop();
        if(best[node]!=current)
            continue;
        for(i=0;i<dim;i++){
            if(capacity[node][g[node][i]]==flow[node][g[node][i]])
                continue;
            distance=current+cost[node][g[node][i]]+old[node]-old[g[node][i]];
            if(distance<best[g[node][i]]){
                best[g[node][i]]=distance;
                real[g[node][i]]=real[node]+cost[node][g[node][i]];
                dad[g[node][i]]=node;
                temp.index=g[node][i];
                temp.cost=best[g[node][i]];
                h.push(temp);
            }
        }
    }
    if(best[d]==inf)
        return 0;
    for(i=0;i<=n+1;i++)
        old[i]=real[i];
    return 1;
}
int main(){
    freopen("cmcm.in","r",stdin);
    freopen("cmcm.out","w",stdout);
    int left,right,m,x,y,a,b,i,j,node,add,maxflow=0,mincost=0;
    scanf("%d%d%d",&left,&right,&m);
    s=0;
    d=left+right+1;
    n=left+right;
    for(i=1;i<=m;i++){
        scanf("%d%d%d",&x,&y,&a);
        y+=left;
        g[x].push_back(y);
        g[y].push_back(x);
        cost[x][y]+=a;
        cost[y][x]-=a;
        capacity[x][y]++;
        index[x][y-left]=i;
    }
    for(i=1;i<=left;i++){
        g[0].push_back(i);
        g[i].push_back(0);
        capacity[0][i]=1;
    }
    for(i=left+1;i<=n;i++){
        g[n+1].push_back(i);
        g[i].push_back(n+1);
        capacity[i][n+1]=1;
    }
    bellman_ford();
    a=0;
    while(dijkstra()==1){
        a++;
        add=inf;
        node=d;
        while(node!=s){
            add=minim(add,capacity[dad[node]][node]-flow[dad[node]][node]);
            node=dad[node];
        }
        node=d;
        while(node!=s){
            flow[dad[node]][node]+=add;
            flow[node][dad[node]]-=add;
            node=dad[node];
        }
        maxflow+=add;
        mincost+=add*real[d];
    }
    printf("%d %d\n",maxflow,mincost);
    for(i=1;i<=left;i++)
        for(j=1;j<=right;j++)
            if(flow[i][j+left]==1)
                printf("%d ",index[i][j]);
    return 0;
}