Cod sursa(job #1733882)

Utilizator alexpetrescuAlexandru Petrescu alexpetrescu Data 25 iulie 2016 23:27:36
Problema Santa Scor 60
Compilator cpp Status done
Runda Arhiva de probleme Marime 5.36 kb
#include <cstdio>
#include <cstdlib>
#include <vector>
#define MOD 666019
#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], vec[MAXB+1];
int z[1<<MAXB][MAXB], h[MAXN+1], hmin[MAXN+1], st[MAXM+1];
int from[MAXN+MAXM+1], g[MAXN+1], u[MAXB][MAXB], c[MAXN+1];
int r[MAXM+1], t[MAXM+1], l[MAXM+1], sef[MOD], urmator[2*MAXM+1];
bool d[1<<MAXB][MAXB], ok[MAXN+MAXM+1], viz[MAXN+1], art[MAXN+1];
long long cine[2*MAXM+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;
    boss++;
    cine[boss]=((1LL*x)<<16)+y;
    urmator[boss]=sef[cine[boss]%MOD];
    sef[cine[boss]%MOD]=boss;
}
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];
    }
}
inline bool apare(int x, int y){
    long long a=((1LL*x)<<16)+y;
    int p=sef[a%MOD];
    while((p)&&(cine[p]!=a)) p=urmator[p];
    return p>0;
}
inline void hamilton(int a, int s, int f){
    int i, j, mask, p;
    if(f!=-1){
        i=0;
        while(f!=v[a][i]) i++;
        f=i;
    }
    i=0;
    while(s!=v[a][i]) i++;
    s=i;
    for(j=0; j<(int)v[a].size(); j++) g[v[a][j]]=j+1;
    for(i=0; i<(int)v[a].size(); i++) for(j=0; j<(int)v[a].size(); j++) if(apare(v[a][i], v[a][j])) u[i][j]=1;
    for(i=1; i<(1<<v[a].size()); i++){
        for(j=0; j<(int)v[a].size(); j++){
            if(i&(1<<j)){
                if(i==(1<<j)){
                    if(j==s) d[i][j]=1;
                    else d[i][j]=0;
                }else{
                    p=0;
                    d[i][j]=0;
                    while((p<(int)v[a].size())&&(d[i][j]==0)){
                        if((p!=j)&&(i&(1<<p))&&(u[j][p])&&(d[i^(1<<j)][p])) d[i][j]=1, z[i][j]=p;
                        p++;
                    }
                }
            }
        }
    }
    for(j=0; j<(int)v[a].size(); j++) g[v[a][j]]=0;
    for(i=0; i<(int)v[a].size(); i++) for(j=0; j<(int)v[a].size(); j++) u[i][j]=0;
    if(f==-1){
        i=0;
        while((i<(int)v[a].size())&&(d[(1<<v[a].size())-1][i]==0)) i++;
        if(i>=(int)v[a].size()) gata(0);
        f=i;
    }else if(d[(1<<(v[a].size()))-1][f]==0) gata(0);
    vec[0]=0;
    mask=(1<<(v[a].size()))-1;
    while(f!=s){
        vec[++vec[0]]=v[a][f];
        mask^=1<<f;
        f=z[mask^(1<<f)][f];
    }
    for(i=vec[0]; i>0; i--) ans[++ans[0]]=vec[i];
}
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);
        }
    }
}