Cod sursa(job #588427)

Utilizator drywaterLazar Vlad drywater Data 7 mai 2011 22:54:27
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.41 kb
#include <stdio.h>
#include <vector>
#include <queue>
#define INF 2000000000
using namespace std;
int j,dist[710],use[710],pred[710],drum,sol,i,n,m,e,x,y,d,edge[711][711],C[710][710],f[710][710];
vector <int> G[711],cost[711];
queue <int> Q;
int bellman()
{
    for (i=1;i<=n+m+2;i++)
    {
        dist[i]=INF;
        pred[i]=-1;
        use[i]=0;
    }
    dist[1]=0;
    use[1]=1;
    Q.push(1);
    while (!Q.empty())
    {
        x=Q.front();
        Q.pop();
        int len=G[x].size();
        for (i=0;i<len;i++)
        {
            y=G[x][i];
            if (C[x][y]-f[x][y]>0 && dist[y]>dist[x]+cost[x][i])
            {
                dist[y]=dist[x]+cost[x][i];
                pred[y]=x;
                if (!use[y])
                {
                    use[y]=1;
                    Q.push(y);
                }
            }
        }
        use[x]=0;
    }
    if (dist[n+m+2]<INF)
    {
        int vmin=INF;
        for (i=n+m+2;i!=1;i=pred[i])
            if (vmin>C[pred[i]][i]-f[pred[i]][i]) vmin=C[pred[i]][i]-f[pred[i]][i];
        for (i=n+m+2;i!=1;i=pred[i])
            {
                f[i][pred[i]]-=vmin;
                f[pred[i]][i]+=vmin;
            }
        return vmin*dist[n+m+2];
    }
    return 0;
}
int main(void)
{
    freopen("cmcm.in","r",stdin);
    freopen("cmcm.out","w",stdout);
    scanf("%d%d%d",&n,&m,&e);
    for (i=1;i<=e;i++)
    {
        scanf("%d%d%d",&x,&y,&d);
        y+=n+1;
        x++;
        G[x].push_back(y); cost[x].push_back(d);
        G[y].push_back(x); cost[y].push_back(-d);
        edge[x][y]=i;
        C[x][y]=1;
    }
    for (i=2;i<=n+1;i++)
    {
        G[1].push_back(i); cost[1].push_back(0);
        G[i].push_back(1); cost[i].push_back(0);
        C[1][i]=1;
    }
    for (i=n+2;i<=n+m+1;i++)
    {
        G[n+m+2].push_back(i); cost[n+m+2].push_back(0);
        G[i].push_back(n+m+2); cost[i].push_back(0);
        C[i][n+m+2]=1;
    }
    drum=1;
    while (drum)
    {
        drum=bellman();
        sol+=drum;
    }
    int nr=0;
    for (i=2;i<=n+1;i++)
        for (j=n+2;j<n+m+2;j++)
            if (f[i][j] && C[i][j])
                {nr++; break;}
    printf("%d %d\n",nr,sol);
    for (i=2;i<=n+1;i++)
        for (j=n+2;j<n+m+2;j++)
            if (f[i][j] && C[i][j])
                {printf("%d ",edge[i][j]); break;}
    printf("\n");
    return 0;
}