Cod sursa(job #1655594)

Utilizator alexpetrescuAlexandru Petrescu alexpetrescu Data 18 martie 2016 09:04:53
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.22 kb
#include <cstdio>
#define INF 1000000000
#define MAXN 602
#define MASK 1023
#define MAXM 51200
int v[MAXN][MAXN+1], id[MAXN][MAXN+1];
int s, d, n, cost[MAXN][MAXN], c[MAXN][MAXN], f[MAXN][MAXN];
int dist[MAXN], q[MASK+1], sol[MAXN], from[MAXN];
bool ok[MAXN];
inline void adauga(int x, int y, int z, int t, int u){
    v[x][++v[x][0]]=y;
    id[x][++id[x][0]]=u;
    cost[x][y]=t;
    c[x][y]=z;
}
inline bool bellman(){
    int i, st, dr, y, x;
    for(i=0; i<n; i++){
        dist[i]=INF;
    }
    dist[s]=0;
    q[0]=s;
    ok[s]=1;
    st=0;
    dr=1;
    while(st<dr){
        x=q[st&MASK];
        ok[x]=0;
        st++;
        for(i=1; i<=v[x][0]; i++){
            y=v[x][i];
            if((c[x][y]>f[x][y])&&(dist[y]>dist[x]+cost[x][y])){
                dist[y]=dist[x]+cost[x][y];
                from[y]=x;
                if(ok[y]==0){
                    ok[y]=1;
                    q[dr&MASK]=y;
                    dr++;
                }
            }
        }
    }
    return (dist[d]!=INF);
}
int main(){
    int a, b, e, i, x, y, z, ans, rez, u, j;
    FILE *fin, *fout;
    fin=fopen("cmcm.in", "r");
    fout=fopen("cmcm.out", "w");
    fscanf(fin, "%d%d%d", &a, &b, &e);
    for(i=1; i<=e; i++){
        fscanf(fin, "%d%d%d", &x, &y, &z);
        y+=a;
        adauga(x, y, 1, z, i);
        adauga(y, x, 0, -z, i);
    }
    s=0;
    d=a+b+1;
    n=a+b+2;
    for(i=1; i<=a; i++){
        adauga(s, i, 1, 0, 0);
        adauga(i, s, 0, 0, 0);
    }
    for(i=a+1; i<=a+b; i++){
        adauga(i, d, 1, 0, 0);
        adauga(d, i, 0, 0, 0);
    }
    rez=0;
    ans=0;
    while(bellman()){
        rez++;
        x=d;
        while(x!=s){
            f[from[x]][x]++;
            f[x][from[x]]--;
            ans+=cost[from[x]][x];
            x=from[x];
        }
    }
    fprintf(fout, "%d %d\n", rez, ans);
    u=0;
    for(i=1; i<=a; i++){
        for(j=1; j<=v[i][0]; j++){
            if((a+1<=v[i][j])&&(v[i][j]<=a+b)&&(c[i][v[i][j]]==f[i][v[i][j]])){
                sol[u++]=id[i][j];
            }
        }
    }
    for(i=0; i<u; i++){
        fprintf(fout, "%d ", sol[i]);
    }
    fclose(fin);
    fclose(fout);
    return 0;
}