Cod sursa(job #2068923)

Utilizator Bodo171Bogdan Pop Bodo171 Data 18 noiembrie 2017 11:37:48
Problema Santa Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.49 kb
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
const int nmax=130005;
const int bmax=17;
vector< pair<int,int> > v[nmax];
vector<int> V[nmax+50005],l[nmax];
int ag[nmax],st[nmax],lev[nmax],low[nmax],norm[nmax],comps[nmax],viz[nmax+50005],x[nmax],y[nmax],ans[nmax];
int ad[bmax][bmax],prc[(1<<16)][bmax],rep[bmax];
int  n,m,u,bcc,s,e,q,found,j,nr,T1,T2,nochance,i,k,X,tip,cnt,rez,aux;
void mark(int X)
{
    l[ bcc ].push_back(st[ u ]);
    if(ag[ u ]){V[ n+bcc].push_back(ag[ u ]);ag[ u ]=0;}
    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])
        {
            st[ ++u ]=v[ x ][ i ].second;lev[nod]=lev[ x ]+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]=x;
                }
        }else
        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)//fa debug mai ales la astea 2
{
    if(prc[state][nod]==-1)
    {
        ans[ ++rez ]=rep[nod+1];
        if(state!=0)
            nochance=1;
        return;
    }
    if(!(state&(state-1))) {ans[ ++rez ]=rep[nod+1];return;}
    reco(state-(1<<nod),prc[state][nod]);
    ans[ ++rez ]=rep[nod+1];
}
void ham(int B,int inc,int sf)
{
   nr=0;
   for(i=0;i<l[B].size();i++)
   {
       add(l[B][ i ]);
   }
   for(i=0;i<(1<<nr);i++)
      for(j=0;j<nr;j++)
       prc[i][j]=-1;
   prc[(1<<(norm[inc]-1))][norm[inc]-1]=0;
   for(i=0;i<(1<<nr);i++)
      for(j=0;j<nr;j++)
        if(prc[i][j]!=-1)
      {
          for(k=1;k<=ad[j][0];k++)
          {
              X=ad[ j ][k];
              if(!(i&(1<<X)))
              {
                  prc[(i|(1<<X))][X]=j;
              }
          }
      }
    bool ok=0;
    if(sf==-1)
    {
        for(i=0;i<nr&&ok==0;i++)
            if(prc[(1<<nr)-1][i]!=-1)
               reco((1<<nr)-1,i),ok=1;
        if(!ok) nochance=1;
    }
    else 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)
{
    for(int i=0;i<l[bico].size();i++)
        if(x[l[bico][ i ]]==nod||y[l[bico][ i ]]==nod)
         return 1;
    return 0;
}
int main()
{
    ifstream f("santa.in");
    ofstream g("santa.out");
    f>>n>>m;
    for(i=1;i<=m;i++)
    {
        f>>x[ i ]>>y[ i ];
        v[ x[ i ] ].push_back({y[ i ],i});
        v[ y[ i ] ].push_back({x[ i ],i});
    }
    f>>s>>e>>q;
    lev[1]=1;
    dfs(1);
    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)
    {
        ham(comps[ 2 ],q,comps[ 3 ]);
        for(cnt=2;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)
    {
        ham(comps[ u-1 ],q,comps[u-2]);
        for(i=u-3;i>0;i-=2)
            {
                if(i==2) ham(comps[ cnt ]-n,comps[ cnt+1 ],-1 );
                else ham(comps[ cnt ]-n,comps[ cnt+1 ],comps[ cnt-1 ] );
            }
    }
    if(tip==3)
    {
       ham(comps[2]-n,1,-1);
    }
    if(nochance) g<<"No chance";
    else
    {
        g<<rez<<'\n';
        for(i=1;i<=rez;i++)
            g<<ans[ i ]<<' ';
    }
    return 0;
}