Cod sursa(job #976985)

Utilizator andrettiAndretti Naiden andretti Data 24 iulie 2013 15:16:05
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.33 kb
#include<stdio.h>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
#define pb push_back
#define maxn 650
#define inf 0x3f3f3f3f
using namespace std;

int n,nL,nR,m,nh,flow,flowcost,source,sink;
int h[maxn],pos[maxn],d[maxn],oldd[maxn],reald[maxn],father[maxn],mch[maxn][maxn];
int cap[maxn][maxn],f[maxn][maxn],cost[maxn][maxn];
bool inside[maxn];
vector <int> l[maxn];

void read()
{
    int x,y,cst;
    scanf("%d%d%d",&nL,&nR,&m);
    source=1;
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d%d",&x,&y,&cst);
        x++; y+=nL+1;
        l[x].pb(y);
        l[y].pb(x);
        cap[x][y]=1;
        cost[x][y]=cst;
        cost[y][x]=-cst;
        mch[x][y]=i;
    }

    for(int i=2;i<=nL+1;i++)
    {
        l[source].pb(i);
        l[i].pb(source);
        cap[source][i]=1;
    }
    n=nL+nR+2; sink=n;
    for(int i=nL+2;i<n;i++)
    {
        l[i].pb(sink);
        l[sink].pb(i);
        cap[i][sink]=1;
    }
}

void bellman()
{
    int k;
    queue <int> q;

    memset(oldd,inf,sizeof(oldd)); oldd[source]=0;
    for(q.push(source),inside[source]=true;!q.empty();q.pop(),inside[k]=false)
    {
        k=q.front();
        for(unsigned int i=0;i<l[k].size();i++)
         if(cap[k][l[k][i]] && oldd[k]+cost[k][l[k][i]]<oldd[l[k][i]])
         {
             oldd[l[k][i]]=oldd[k]+cost[k][l[k][i]];
             if(!inside[l[k][i]])
             {
                 q.push(l[k][i]);
                 inside[l[k][i]]=true;
             }
         }
    }
}

void swap(int i,int j)
{
    int aux;
    aux=h[i]; h[i]=h[j]; h[j]=aux;
    pos[h[i]]=i; pos[h[j]]=j;
}

void heap_up(int k)
{
    if(k<=1) return;
    int i=k/2;
    if(d[h[k]]<d[h[i]]) {swap(i,k); heap_up(i);}
}

void heap_dw(int k)
{
    int i=2*k;
    if(i<=nh)
    {
        if(i+1<=nh && d[h[i+1]]<d[h[i]]) i++;
        if(d[h[i]]<d[h[k]]) {swap(i,k); heap_dw(i);}
    }
}

int extract()
{
    swap(1,nh--);
    pos[h[nh+1]]=0;
    return h[nh+1];
}

int dijkstra()
{
    int k,newcost;
    for(int i=1;i<=n;i++) {h[i]=i; pos[i]=i; d[i]=inf; father[i]=0;}
    d[source]=reald[source]=0;
    nh=n;

    while(nh>0)
    {
        k=extract();
        heap_dw(1);

        for(unsigned int i=0;i<l[k].size();i++)
         if(pos[l[k][i]] && f[k][l[k][i]]<cap[k][l[k][i]])
         {
             newcost=d[k]+cost[k][l[k][i]]+oldd[k]-oldd[l[k][i]];
             if(newcost<d[l[k][i]])
             {
                 d[l[k][i]]=newcost;
                 reald[l[k][i]]=reald[k]+cost[k][l[k][i]];
                 father[l[k][i]]=k;
                 heap_up(pos[l[k][i]]);
             }

         }
    }
    memcpy(oldd,reald,sizeof(reald));
    if(d[sink]==inf) return 0;
    return 1;
}

void update()
{
    int i;
    for(i=sink;father[i];i=father[i])
    {
        f[father[i]][i]+=1;
        f[i][father[i]]-=1;
    }
    flow++;
    flowcost+=reald[sink];
}

void print()
{
    printf("%d %d\n",flow,flowcost);
    for(int i=2;i<=nL+1;i++)
     for(int j=nL+2;j<n;j++)
      if(f[i][j])
       printf("%d ",mch[i][j]);
}

int main()
{
    freopen("cmcm.in","r",stdin);
    freopen("cmcm.out","w",stdout);

    read();
    bellman();
    while(dijkstra()) update();
    print();

    fclose(stdin);
    fclose(stdout);
    return 0;
}