Cod sursa(job #1655586)

Utilizator alexpetrescuAlexandru Petrescu alexpetrescu Data 18 martie 2016 08:48:09
Problema Cuplaj maxim de cost minim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.29 kb
#include <cstdio>
#define INF 1000000000
#define MAXN 1202
#define MASK 1048575
#define MAXM 50000
int s, d, n, k, cost[MAXN][MAXN], c[MAXN][MAXN], f[MAXN][MAXN], from[MAXN];
int dist[MAXN], q[MASK+1], lista[MAXN], val[2*MAXM+1], next[2*MAXM+1], sol[MAXN];
bool ok[MAXN];
inline void adauga(int x, int y, int z, int t){
    k++;
    val[k]=y;
    next[k]=lista[x];
    lista[x]=k;
    cost[x][y]=t;
    c[x][y]=z;
}
inline bool bellman(){
    int i, st, dr, p, 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++;
        p=lista[x];
        while(p){
            if((c[x][val[p]]>f[x][val[p]])&&(dist[val[p]]>dist[x]+cost[x][val[p]])){
                dist[val[p]]=dist[x]+cost[x][val[p]];
                from[val[p]]=x;
                if(ok[val[p]]==0){
                    ok[val[p]]=1;
                    q[dr&MASK]=val[p];
                    dr++;
                }
            }
            p=next[p];
        }
    }
    return (dist[d]!=INF);
}
int main(){
    int a, b, e, i, x, y, z, ans, rez, u, p;
    FILE *fin, *fout;
    fin=fopen("cmcm.in", "r");
    fout=fopen("cmcm.out", "w");
    fscanf(fin, "%d%d%d", &a, &b, &e);
    for(i=0; i<e; i++){
        fscanf(fin, "%d%d%d", &x, &y, &z);
        y+=a;
        adauga(x, y, 1, z);
        adauga(y, x, 0, -z);
    }
    s=0;
    d=a+b+1;
    n=a+b+2;
    for(i=1; i<=a; i++){
        adauga(s, i, 1, 0);
        adauga(i, s, 0, 0);
    }
    for(i=a+1; i<=a+b; i++){
        adauga(i, d, 1, 0);
        adauga(d, i, 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++){
        p=lista[i];
        while(p){
            if((a+1<=val[p])&&(val[p]<=a+b)&&(f[i][val[p]]==c[i][val[p]])){
                sol[u++]=(p+1)/2;
            }
            p=next[p];
        }
    }
    for(i=0; i<u; i++){
        fprintf(fout, "%d ", sol[i]);
    }
    fclose(fin);
    fclose(fout);
    return 0;
}