Cod sursa(job #2070232)

Utilizator Bodo171Bogdan Pop Bodo171 Data 19 noiembrie 2017 12:55:28
Problema Santa Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 5.94 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
using namespace std;
const int nmax=130005;
const int bmax=17;
vector< pair<int,int> > v[nmax];
vector<int> V[nmax+50005],l[nmax],ag[nmax];
int st[nmax+50005],lev[nmax],low[nmax],norm[nmax],comps[nmax+50005],viz[nmax+50005],x[nmax],y[nmax],ans[nmax+50005],nans[nmax],ap[nmax],B[nmax];
int ad[bmax][bmax],rep[bmax];
char prc[bmax][(1<<15)+5];
int vis[bmax][(1<<15)+5];
int n,m,u,bcc,s,e,q,found,j,nr,T1,T2,nochance,i,k,X,tip,cnt,rez,aux,nrez;
string str;
int num,ch;
void baga(int x)
{
    if(B[x]&&B[x]!=bcc) B[x]=-1;
    else B[x]=bcc;
}
void mark(int X)
{
    l[ bcc ].push_back(st[u]);
    baga(x[st[u]]);
    baga(y[st[u]]);
    while(!ag[ u ].empty())
    {
        V[ n+bcc].push_back(ag[ u ].back());
        V[ag[u].back()].push_back(n+bcc);
        ag[ u ].pop_back();
    }
    if(st[ u ]==X)
    {
        u--;
        return;
    }
    u--;
    mark(X);
}
void dfs(int x)
{
    int nod=0,et=0;
    low[x]=(1<<30);
    for(int i=0; i<v[ x ].size(); i++)
    {
        nod=v[ x ][ i ].first;
        et=v[ x ][ i ].second;
        if(!lev[nod])
        {
            lev[nod]=lev[ x ]+1;
            if(!ap[et])st[ ++u ]=et;
            ap[et]=1;
            dfs(nod);
            if(low[nod]<low[x])
                low[x]=low[nod];
            if(low[nod]>=lev[ x ])
            {
                bcc++;
                mark(et);
                V[n+bcc].push_back( x );
                V[ x ].push_back(n+bcc);
                ag[u].push_back(x);
            }
        }
        else
        {
            if(!ap[et])st[++u]=et;
            ap[et]=1;
            if(lev[nod]<low[x])
                low[x]=lev[nod];
        }
    }
}
void defeseu(int x)
{
    viz[ x ]=1;
    st[ ++u ]=x;
    if(x==e)
    {
        found=1;
        aux=u;
        for(j=1; j<=u; j++)
            comps[j]=st[j];
        return;
    }
    for(int i=0; i<V[ x ].size(); i++)
        if((!found)&&(!viz[V[ x ][ i ]]))
            defeseu(V[ x ][ i ]);
    u--;
}
void add(int p)
{
    if(!norm[ x[p] ])
    {
        norm[ x[p] ]=++nr;
        rep[nr]=x[p];
    }
    if(!norm[ y[p] ])
    {
        norm[ y[p] ]=++nr;
        rep[nr]=y[p];
    }
    T1=norm[ x[p] ]-1;
    T2=norm[ y[p] ]-1;
    ad[T1][++ad[T1][0]]=T2;
    ad[T2][++ad[T2][0]]=T1;
}
void del(int X)
{
    norm[X]=0;
}
void reco(int state,int nod)
{
    if(vis[nod][state]!=cnt)
    {
        if(state!=0)ans[ ++rez ]=rep[nod+1];
        if(state!=0)
            nochance=1;
        return;
    }
    reco(state-(1<<nod),prc[nod][state]);
    ans[ ++rez ]=rep[nod+1];
}
void memo(int state,int nod)
{
    if(vis[nod][state]==cnt) return;
    vis[nod][state]=cnt;prc[nod][state]=-1;
    for(int j=1; j<=ad[nod][0]; j++)
        if((state&(1<<ad[nod][j])))
        {
            memo(state-(1<<nod),ad[nod][j]);
            if(prc[ad[nod][j]][state-(1<<nod)]!=-1)
            {
                prc[nod][state]=ad[nod][j];
                return;
            }
        }
}
void ham(int B,int inc,int sf)
{
    nr=0;
    for(i=0; i<l[B].size(); i++)
    {
        add(l[B][ i ]);
    }
    prc[norm[inc]-1][(1<<(norm[inc]-1))]=0;vis[norm[inc]-1][(1<<(norm[inc]-1))]=cnt;
    bool ok=0;
    if(sf==-1)
    {
        for(i=0; i<nr&&ok==0; i++)
        {
            memo((1<<nr)-1,i);
            if(prc[i][(1<<nr)-1]>-1)
                ok=1;
        }
        ok=0;
        for(i=0; i<nr&&ok==0; i++)
            if(prc[i][(1<<nr)-1]!=-1)
                reco((1<<nr)-1,i),ok=1;
        if(!ok) nochance=1;
    }
    else
    {
        memo((1<<nr)-1,norm[sf]-1);
        reco((1<<nr)-1,norm[sf]-1);
    }
    for(i=0; i<l[B].size(); i++)
    {
        del(x[l[B][ i ]]);
        del(y[l[B][ i ]]);
    }
    for(i=0; i<=nr; i++)
        ad[i][0]=0;
}
bool in(int nod,int bico)
{
    if(bico<0) return 0;
    for(int i=0; i<l[bico].size(); i++)
    {
        if(x[l[bico][ i ]]==nod||y[l[bico][ i ]]==nod)
            return 1;
    }
    return 0;
}
void comprima()
{
    for(i=1; i<=rez; i++)
    {
        if(ans[i]!=ans[i+1])
            nans[++nrez]=ans[i];
    }
    rez=nrez;
    for(i=1; i<=nrez; i++)
        ans[i]=nans[i];
}
int getnum()
{
    num=0;
    while(str[ch]>='0'&&str[ch]<='9')
    {
        num=num*10+str[ch]-'0';
        ch++;
    }
    ch++;
    return num;
}
int main()
{
    ifstream f("santa.in");
    ofstream g("santa.out");
    f>>n>>m;
    getline(f,str);
    for(i=1; i<=m; i++)
    {
        getline(f,str);
        ch=0;
        x[i]=getnum();
        y[i]=getnum();
        v[ x[ i ] ].push_back({y[ i ],i});
        v[ y[ i ] ].push_back({x[ i ],i});
    }
    f>>s>>e>>q;
    lev[s]=1;
    dfs(s);
    for(i=1; i<=n; i++)
        if(B[i]>0)
        {
            V[i].push_back(B[i]+n);
            V[B[i]+n].push_back(i);
        }
    defeseu(s);//grija cum refolosesti stiva
    u=aux;
    if(in(q,comps[2]-n)) tip=1;
    if(in(q,comps[u-1]-n)) tip+=2;
    if(tip==0)
    {
        g<<"No chance";
        return 0;
    }
    if(tip==1)
    {
        cnt=2;
        ham(comps[ 2 ]-n,q,comps[ 3 ]);
        for(cnt=4; cnt<=u; cnt+=2)
        {
            if(cnt==u-1) ham(comps[ cnt ]-n,comps[ cnt-1 ],-1);
            else ham(comps[ cnt ]-n,comps[ cnt-1 ],comps[ cnt+1 ] );
        }
    }
    if(tip==2)
    {
        cnt=u-1;
        ham(comps[ u-1 ]-n,q,comps[u-2]);
        for(cnt=u-3; cnt>0; cnt-=2)
        {
            if(cnt==2) ham(comps[ cnt ]-n,comps[ cnt+1 ],-1 );
            else ham(comps[ cnt ]-n,comps[ cnt+1 ],comps[ cnt-1 ] );
        }
    }
    if(tip==3)
    {
        cnt=1;
        ham(comps[2]-n,q,-1);
        if(u>3) nochance=1;
    }
    comprima();
    if(nochance) g<<"No chance";
    else
    {
        g<<rez<<'\n';
        for(i=1; i<=rez; i++)
            g<<ans[ i ]<<' ';
    }
    return 0;
}