Cod sursa(job #1642232)

Utilizator alexpetrescuAlexandru Petrescu alexpetrescu Data 9 martie 2016 13:16:01
Problema Cc Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.11 kb
#include <cstdio>
#define INF 1000000000
#define MASK 255
#define MAXN 100
int n, s, t, d[2*MAXN+2], c[2*MAXN+2][2*MAXN+2], f[2*MAXN+2][2*MAXN+2], from[2*MAXN+2], q[MASK+1], e[2*MAXN+2][2*MAXN+2];
bool aci[2*MAXN+2];
int k, val[2*(2*MAXN+2)*(2*MAXN+2)], next[2*(2*MAXN+2)*(2*MAXN+2)], lista[2*MAXN+2];
inline void adauga(int x, int y){
    k++;
    val[k]=y;
    next[k]=lista[x];
    lista[x]=k;
}
inline bool bellman(){
    int st, dr, i, p;
    d[0]=0;
    for(i=1; i<=2*n+1; i++){
        d[i]=INF;
    }
    st=0;
    q[0]=s;
    dr=1;
    aci[s]=1;
    while(st<dr){
        p=lista[q[st&MASK]];
        while(p){
            i=val[p];
            if((c[q[st&MASK]][i]>f[q[st&MASK]][i])&&(d[i]>e[q[st&MASK]][i]+d[q[st&MASK]])){
                d[i]=e[q[st&MASK]][i]+d[q[st&MASK]];
                from[i]=q[st&MASK];
                if(aci[i]==0){
                    aci[i]=1;
                    q[dr&MASK]=i;
                    dr++;
                }
            }
            p=next[p];
        }
        aci[q[st&MASK]]=0;
        st++;
    }
    return (d[t]<INF);
}
int main(){
    int i, j, min, ans;
    FILE *fin, *fout;
    fin=fopen("cc.in", "r");
    fout=fopen("cc.out", "w");
    fscanf(fin, "%d", &n);
    s=0;
    t=2*n+1;
    for(i=1; i<=n; i++){
        for(j=n+1; j<=2*n; j++){
            fscanf(fin, "%d", &e[i][j]);
            adauga(i, j);
            adauga(j, i);
            e[j][i]=-e[i][j];
            c[i][j]=1;
        }
        adauga(s, i);
        adauga(i, s);
        c[s][i]=1;
        adauga(i+n, t);
        adauga(t, i+n);
        c[i+n][t]=1;
    }
    ans=0;
    while(bellman()){
        ans+=d[t];
        i=t;
        min=INF;
        while(i!=s){
            if(min>c[from[i]][i]-f[from[i]][i]){
                min=c[from[i]][i]-f[from[i]][i];
            }
            i=from[i];
        }
        i=t;
        while(i!=s){
            f[from[i]][i]+=min;
            f[i][from[i]]-=min;
            i=from[i];
        }
    }
    fprintf(fout, "%d\n", ans);
    fclose(fin);
    fclose(fout);
    return 0;
}