Cod sursa(job #1733891)

Utilizator alexpetrescuAlexandru Petrescu alexpetrescu Data 25 iulie 2016 23:52:54
Problema Santa Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.06 kb
#include <cstdio>
#include <cstdlib>
#include <vector>
#define MAXN 45000
#define MAXM 130000
#define MAXB 15
std::vector<int>v[MAXM];
int S, E, Q, m, o, vf, k, found, q, boss;
int e[2*MAXM+1], urm[2*MAXM+1], val[2*MAXM+1], next[2*MAXM+1];
int list[MAXN+MAXM+1], lista[MAXN+1], ans[MAXN+1], l[MAXN+MAXM+1];
int h[MAXN+1], hmin[MAXN+1], st[MAXM+1], t[MAXN+MAXM+1];
int from[MAXN+MAXM+1], c[MAXN+MAXM+1], r[MAXN+MAXM+1];
bool ok[MAXN+MAXM+1], viz[MAXN+1], art[MAXN+1], rege[MAXN+1];
FILE *fin, *fout;
inline void gata(bool w){
    if(w){
        fprintf(fout, "%d\n%d", ans[0]+1, Q);
        for(int i=1; i<=ans[0]; i++) fprintf(fout, " %d", ans[i]);
        fprintf(fout, "\n");
    }else fprintf(fout, "No chance\n");
    fclose(fin);
    fclose(fout);
    exit(0);
}
inline void adauga(int x, int y){
    m++;
    val[m]=y;
    next[m]=lista[x];
    lista[x]=m;
}
inline void add(int x, int y){
    if(ok[val[2*y+1]]==0) ok[val[2*y+1]]=1, v[x].push_back(val[2*y+1]);
    if(ok[val[2*y+2]]==0) ok[val[2*y+2]]=1, v[x].push_back(val[2*y+2]);
}
void dfs(int x){
    int p=lista[x];
    viz[x]=1;
    hmin[x]=h[x];
    while(p){
        if(viz[val[p]]){
            if(h[val[p]]<hmin[x]) hmin[x]=h[val[p]];
        }else{
            h[val[p]]=h[x]+1;
            st[++vf]=(p-1)/2;
            dfs(val[p]);
            if(hmin[val[p]]<h[x]){
                if(hmin[val[p]]<hmin[x]) hmin[x]=hmin[val[p]];
            }else{
                art[x]=1;
                while(st[vf]!=(p-1)/2){
                    add(k, st[vf]);
                    vf--;
                }
                add(k, st[vf]);
                vf--;
                for(int i=0; i<(int)v[k].size(); i++) ok[v[k][i]]=0;
                k++;
            }
        }
        p=next[p];
    }
}
inline void muchie(int x, int y){
    o++;
    e[o]=y;
    urm[o]=list[x];
    list[x]=o;
}
void drum(int x){
    int p=list[x];
    ok[x]=1;
    while(p){
        if(ok[e[p]]==0){
            from[e[p]]=x;
            if((found==-1)&&(e[p]<k)) for(int i=0; i<(int)v[e[p]].size(); i++) if(v[e[p]][i]==E) found=e[p];
            drum(e[p]);
        }
        p=urm[p];
    }
}
bool bkt(int p, int q, int x, int y){
    rege[x]=0;
    if(p>1) ans[++ans[0]]=x;
    if(p==q){
        if((y==-1)||(x==y)) return 1;
        rege[x]=1;
        ans[0]--;
        return 0;
    }
    int i=lista[x];
    while(i){
        if((rege[val[i]])&&((val[i]!=y)||(p==q-1))&&(bkt(p+1, q, val[i], y))) return 1;
        i=next[i];
    }
    rege[x]=1;
    ans[0]--;
    return 0;
}
inline void hamilton(int a, int s, int f){
    for(int i=0; i<(int)v[a].size(); i++) rege[v[a][i]]=1;
    if(!bkt(1, v[a].size(), s, f)) gata(0);
}
int main(){
    int n, tz, i, x, y, sh, j;
    bool chill;
    fin=fopen("santa.in", "r");
    fout=fopen("santa.out", "w");
    fscanf(fin, "%d%d", &n, &tz);
    for(i=0; i<tz; i++){
        fscanf(fin, "%d%d", &x, &y);
        adauga(x, y);
        adauga(y, x);
    }
    fscanf(fin, "%d%d%d", &S, &E, &Q);
    dfs(S);
    sh=0;
    for(i=1; i<=n; i++) if(art[i]){
        c[i]=sh+k;
        r[sh]=i;
        sh++;
    }
    for(i=0; i<k; i++) for(j=0; j<(int)v[i].size(); j++) if(art[v[i][j]]) muchie(i, c[v[i][j]]), muchie(c[v[i][j]], i);
    found=-1;
    drum(c[S]);
    x=found;
    while(from[x]!=c[S]){
        t[q]=x;
        l[q]=r[from[x]-k];
        q++;
        x=from[from[x]];
    }
    t[q]=x;
    q++;
    chill=0;
    for(i=0; i<(int)v[t[0]].size(); i++) chill|=(v[t[0]][i]==Q);
    for(i=0; i<(int)v[t[q-1]].size(); i++) chill|=(v[t[q-1]][i]==Q);
    if(chill==0) gata(0);
    else{
        chill=0;
        for(i=0; i<(int)v[t[0]].size(); i++) chill|=(v[t[0]][i]==Q);
        if(chill){
            l[q-1]=-1;
            hamilton(t[0], Q, l[0]);
            for(i=1; i<q; i++) hamilton(t[i], l[i-1], l[i]);
            gata(1);
        }else{
            l[q-1]=Q;
            for(i=q-1; i>0; i--) hamilton(t[i], l[i], l[i-1]);
            hamilton(t[0], l[0], -1);
            gata(1);
        }
    }
}