Cod sursa(job #567917)

Utilizator irene_mFMI Irina Iancu irene_m Data 30 martie 2011 16:48:06
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.02 kb
#include <cstdio>
#include <vector>
#define MaxN 750
#define MAX 1000005
#define Inf 0x3f3f3f3f
#define infile "cmcm.in"
#define outfile "cmcm.out"

using namespace std;

vector <int> G[MaxN];

int N,M,E,cap[MaxN][MaxN],cost[MaxN][MaxN],nr[MaxN][MaxN],b[MaxN][MaxN];
int Q[MAX],dist[MaxN],uz[MaxN],t[MaxN];
int NR,S,D,sw=1,MIN;
long long CT;

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;
            G[x].push_back(y); G[y].push_back(x);
            cost[x][y]=z; cost[y][x]=-z;
            nr[x][y]=i;
            cap[x][y]=1;
      }
}

void graph()
{
      int i;
      S=1; D=N+M+2;
      for(i=2;i<=N+1;i++)
      {
            G[1].push_back(i); G[i].push_back(1);
            cap[1][i]=1;
      }

      for(i=N+2;i<=N+M+1;i++)
      {
            G[i].push_back(D); G[D].push_back(i);
            cap[i][D]=1;
      }
}

void BF()
{
      int i,p=1,x,y,nr,j,n=N+M+2;

      for(i=1;i<=n;i++)
            t[i]=-1, uz[i]=0, dist[i]=Inf;

      sw=0;
      uz[S]=1; dist[S]=0;
      Q[1]=S;
      for(i=1;i<=p;i++)
      {
            x=Q[i]; nr=G[x].size();
            for(j=0;j<nr;j++)
            {
                  y=G[x][j];
                  if(cap[x][y]-b[x][y]>0 && dist[x]+cost[x][y]<dist[y])
                  {
                        dist[y]=dist[x]+cost[x][y];
                        t[y]=x;
                        if(!uz[y])
                        {
                              uz[y]=1;
                              Q[++p]=y;
                        }
                  }
            }
            uz[x]=0;
      }
      if(dist[D]<Inf)
            sw=1;
}

void solve()
{
      int nod;
      do{
            BF();
            if(sw)
            {
                  MIN=Inf;
                  for(nod=D;nod!=S;nod=t[nod])
                        if(cap[t[nod]][nod]-b[t[nod]][nod]<MIN)
                              MIN=cap[t[nod]][nod]-b[t[nod]][nod];
                  for(nod=D;nod!=S;nod=t[nod])
                  {
                        b[t[nod]][nod]+=MIN;
                        b[nod][t[nod]]-=MIN;
                  }
                  CT+=((long long)dist[D]*MIN);
            }
      }while(sw);
}

void write()
{
      int i,j;
      for(i=2;i<=N+1;i++)
            for(j=N+2;j<=N+M+1;j++)
                  if(b[i][j] && cap[i][j])
                  {
                        NR++;
                        break;
                  }
      printf("%d %lld\n",NR,CT);
      for(i=2;i<=N+1;i++)
            for(j=N+2;j<=N+M+1;j++)
                  if(b[i][j] && cap[i][j])
                  {
                        printf("%d ",nr[i][j]);
                        break;
                  }
}

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

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

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