Cod sursa(job #727538)

Utilizator ioalexno1Alexandru Bunget ioalexno1 Data 28 martie 2012 02:23:29
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.42 kb
#include <cstdio>
#include <vector>
#define N 605
#define E 50005
#define inf 1999999999
using namespace std;
int cap[N][N],cost[N][N],flux[N][N],muc[N][N],c[N*N];
int n,m,SS,SD;
int ctotal,k,sol[E],dist[N],tata[N];
bool viz[N];
vector <int> nod[N];
void read()
{ int e,x,y,z,i;
freopen("cmcm.in","r",stdin); scanf("%d %d %d\n",&n,&m,&e);
for(i=1;i<=e;++i)
    {
    scanf("%d %d %d\n",&x,&y,&z);
    muc[x][y+n]=i;
    nod[x].push_back(y+n);
    nod[y+n].push_back(x);
    cost[x][y+n]=z;
    cost[y+n][x]=-z;
    cap[x][y+n]=1;
    }
fclose(stdin);
}
int bellman_ford()
{ int i,x,y,p,u;
for(i=1;i<=n+m;++i)
    {
    dist[i]=inf;
    viz[i]=0;
    tata[i]=0;
    }
p=u=1;
dist[SD]=inf; tata[SD]=0;
dist[SS]=0;
c[1]=SS;
vector <int>::iterator it;
while(p<=u)
    {
    x=c[p]; viz[x]=0;
    for(it=nod[x].begin();it!=nod[x].end();++it)
        {
        y=*it;
        if(cap[x][y]>flux[x][y])
            {
            if(dist[x]+cost[x][y]<dist[y])
                {
                dist[y]=dist[x]+cost[x][y];
                tata[y]=x;
                if(viz[y]==0)
                    {
                    c[++u]=y;
                    viz[y]=1;
                    }
                }
            }
        }
    ++p;
    }
if(dist[SD]!=inf)return 1;
    else return 0;
}
inline int min(int x,int y)
{
if(x<y)return x;
    else return y;
}
void solve()
{ int fm,i;
while(bellman_ford())
    {
    fm=inf;
    for(i=SD;i!=SS;i=tata[i])
        fm=min(fm,cap[tata[i]][i]-flux[tata[i]][i]);
    if(fm)
        {
        for(i=SD;i!=SS;i=tata[i])
            {
            flux[tata[i]][i]+=fm;
            flux[i][tata[i]]-=fm;
            }
        }
    }
}
void reconstr_sol()
{ int i,j;
ctotal=0; k=0;
for(i=1;i<=n;++i)
    for(j=1;j<=m;++j)
        if(flux[i][j+n]==1)
            {
            ctotal+=cost[i][j+n];
            sol[++k]=muc[i][j+n];
            }
}
void write()
{ int i;
freopen("cmcm.out","w",stdout); printf("%d %d\n",k,ctotal);
for(i=1;i<=k;++i)printf("%d ",sol[i]);
fclose(stdout);
}
int main()
{ int i;
read();
SS=601; // super sursa;
SD=602; // super destinatie
for(i=1;i<=n;++i)
    {
    nod[SS].push_back(i);
    nod[i].push_back(SS);
    cap[SS][i]=1;
    }
for(i=1;i<=m;++i)
    {
    nod[i+n].push_back(SD);
    nod[SD].push_back(i+n);
    cap[i+n][SD]=1;
    }
solve();
reconstr_sol();
write();
return 0;
}