BZOJ3421 : Poi2013 Walk

最多只有一个连通块大小大于$nk$,所以用hash表进行BFS的时候只扩展$nk$步即可。

时间复杂度$O(n^2k)$。

 

#include<cstdio>
typedef long long ll;
const int N=5001000,M=9999991;
int n,m,lim,i,h=1,t,g[M],nxt[N],ed;ll v[N],a[N/5],q[N],x,S,T;char s[70];
inline void del(ll x){
  int u=x%M;
  v[ed]=x;nxt[ed]=g[u];g[u]=ed++;
}
inline void add(ll x){
  int u=x%M;
  for(int i=g[u];i;i=nxt[i])if(v[i]==x)return;
  v[ed]=x;nxt[ed]=g[u];g[u]=ed++;q[++t]=x;
}
inline ll read(){
  ll t=0;
  scanf("%s",s);
  for(int i=0;i<n;i++)t=t*2+s[i]-'0';
  return t;
}
int main(){
  scanf("%d%d",&n,&m);lim=n*m+5;
  add(S=read());T=read();
  for(i=0;i<m;i++)del(a[i]=read());
  while(h<=t&&t<=lim){
    x=q[h++];
    if(x==T)return puts("TAK"),0;
    for(i=0;i<n;i++)add(x^(1LL<<i));
  }
  if(t<=lim)return puts("NIE"),0;
  for(h=1,t=ed=i=0;i<M;i++)g[i]=0;
  add(T);
  for(i=0;i<m;i++)del(a[i]);
  while(h<=t&&t<=lim){
    x=q[h++];
    if(x==S)return puts("TAK"),0;
    for(i=0;i<n;i++)add(x^(1LL<<i));
  }
  return puts(t<=lim?"NIE":"TAK"),0;
}

  

posted @ 2016-03-16 18:04  Claris  阅读(478)  评论(0编辑  收藏  举报