Cod sursa(job #429010)

Utilizator irene_mFMI Irina Iancu irene_m Data 29 martie 2010 19:30:08
Problema Cuplaj maxim de cost minim Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 2.99 kb
#include <cstdio>
#define infile "cmcm.in"
#define outfile "cmcm.out"
#define MaxN 724
#define Inf 0x3f3f3f3f

struct edge{
      int x,c;
      edge *next;
}     *G[MaxN];

int N,M,E,S,D,nr,ok=1,sol,flux;
int Q[MaxN*MaxN],tt[MaxN],dist[MaxN],uz[MaxN];
int c[MaxN][MaxN],f[MaxN][MaxN],a[MaxN][MaxN];

void add(int x,int y,int c)
{
      edge *q=new edge;
      q->x=y; q->c=c; q->next=G[x]; G[x]=q;
}

void read()
{
      int i,x,y,z;
      scanf("%d%d%d",&N,&M,&E);
      for(i=1;i<=E;i++)
      {
            scanf("%d%d%d",&x,&y,&z);
            x++; y+=N+1;
            add(x,y,z); add(y,x,-z);
            a[x][y]=i;
            c[x][y]=1;
      }
}

int minim(int x,int y)
{
      if(x<y)
            return x;
      return y;
}

void build_graph()
{
      S=1; D=N+M+2;
      int i;
      for(i=2;i<=N+1;i++)
      {
            add(S,i,0); add(i,S,0);
            c[1][i]=1;
      }

      for(i=N+2;i<=N+M+1;i++)
      {
            add(i,D,0); add(D,i,0);
            c[i][D]=1;
      }
}

void initial()
{
      int i;
      for(i=2;i<=N+M+2;i++)
            uz[i]=0, dist[i]=Inf, tt[i]=-1;
}

void imbun(int nod)
{
      if(tt[nod])
      {
            if(c[tt[nod]][nod]-f[tt[nod]][nod]<flux)
                 flux=c[tt[nod]][nod]-f[tt[nod]][nod];
            imbun(tt[nod]);
            f[tt[nod]][nod]+=flux;
            f[nod][tt[nod]]-=flux;
      }
}

int BF()
{
      int i,p=1,nod,nodc,st,dr;
      edge *q;

      initial();
      Q[p]=S; uz[S]=1; dist[S]=0;
      st=0; dr=1;

      while(st<=dr)
      {
            st++;
            nodc=Q[st];
            for(q=G[nodc];q;q=q->next)
            {
                  nod=q->x;
                  if(c[nodc][nod]>f[nodc][nod] && dist[nod]>dist[nodc]+q->c)
                  {
                        dist[nod]=dist[nodc]+q->c;
                        tt[nod]=nodc;
                        if(!uz[nod])
                              Q[++dr]=nod, uz[nod]=1;
                  }
            }
            uz[nodc]=0;
      }

      if(dist[D]<Inf)
      {
            flux=Inf;
            imbun(D);
            return flux*dist[D];
      }

      return 0;
}


void solve()
{
      build_graph();

      while(ok)
      {
            ok=BF();
            sol+=ok;
      }
}

void write()
{
      int i,j;
      for(i=2;i<=N+1;i++)
            for(j=N+2;j<=N+M+1;j++)
                  if(c[i][j] && f[i][j])
                  {
                        nr++; break;
                  }

      printf("%d %d\n",nr,sol);

      for(i=2;i<=N+1;i++)
            for(j=N+2;j<=N+M+1;j++)
                  if(c[i][j] && f[i][j])
                  {
                        printf("%d ",a[i][j]);
                        break;
                  }
}

int main()
{
      freopen(infile,"r",stdin);
      freopen(outfile,"w",stdout);

      read();
      solve();
      write();

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