标签:复杂 set front define clu sqrt map out lse
双向bfs,至于为什么不会爆还是因为生日悖论,然后双向bfs降低了时空复杂度,ssqrt(n),
然后就是问题的关键
双向bfs:
1.轮流拓展:
会导致一个方向出现了可行解,另一个方向还没出现,无法构成最优,
2.按层拓展:不会出现,ac
3.按size拓展:同1,也会出现该种情况
按size拓展:
#include<cstdio> #include<cstring> #include<iostream> #include<queue> #include<set> #include<map> #define LL long long using namespace std; const int maxn=5e6+5;//根据生日悖论,只需要找 sqrt(p)次就可以找到答案 struct Node{ int num; int step; int op; int pre; Node():num(num),step(step),op(op),pre(pre){} Node(int _num,int _step,int _op,int _pre){ num=_num; step=_step; op=_op; pre=_pre; } }q[maxn][2]; LL x,y; void exgcd(LL a,LL b){ if(!b){ x=1ll; y=0ll; return; } exgcd(b,a%b); LL temp=y; y=x-a/b*y; x=temp; } inline LL get_inv(LL a,LL p){ exgcd(a,p); return (x%p+p)%p; } int u,v; LL p; set<int >se[2];//数字 map<int ,int>dis[2]; int front[2],rear[2]; void Dfs(int kk){ if(q[kk][0].pre<0)return; Dfs(q[kk][0].pre); printf("%d ",q[kk][0].op); } void Dfs2(int kk){ if(q[kk][1].pre<0)return; printf("%d ",q[kk][1].op); Dfs2(q[kk][1].pre); } inline void bfs(int u,int v){ q[rear[0]++][0]=(Node(u,0,0,-1));//正向 q[rear[1]++][1]=(Node(v,0,0,-1));//反向 dis[0][u]=dis[1][v]=0; se[0].insert(u); se[1].insert(v); int now=0; while(front[0]<rear[0] || front[1]<rear[1]){ /*if(rear[0]>maxn ||rear[1]>maxn ) { cout<<"shit"; exit(0); }*/ //if((front[0]==rear[0] ||q[front[0]][0].step!=now )&& (front[1]==rear[1] || q[front[1]][1].step!=now))now++; if(rear[0]-front[0]<rear[1]-front[1]){//正向 //printf("%d____",front[0]); Node s=q[front[0]][0]; if(se[1].find(s.num)!=se[1].end()){ printf("%d\n",s.step+q[dis[1][s.num]][1].step); Dfs(front[0]);Dfs2(dis[1][s.num]); break; } int to=(s.num+1)%p; if(se[0].find(to)==se[0].end()){ dis[0][to]=rear[0]; q[rear[0]++][0]=(Node(to,s.step+1,1,front[0])); se[0].insert(to); //printf("%d\n",to); } to=((LL)s.num+p-1)%p; if(se[0].find(to)==se[0].end()){ dis[0][to]=rear[0]; q[rear[0]++][0]=(Node(to,s.step+1,2,front[0])); se[0].insert(to); //printf("%d\n",to); } to=get_inv((LL)s.num,p); if(se[0].find(to)==se[0].end()){ dis[0][to]=rear[0]; q[rear[0]++][0]=(Node(to,s.step+1,3,front[0])); se[0].insert(to);//printf("%d\n",to); } front[0]++; } else {//反向 //printf("___%d ",front[1]); Node s=q[front[1]][1]; if(se[0].find(s.num)!=se[0].end()){ printf("%d\n",s.step+q[dis[0][s.num]][0].step); Dfs(dis[0][s.num]);Dfs2(front[1]); break; } int to=(s.num+1)%p; if(se[1].find(to)==se[1].end()){ dis[1][to]=rear[1]; q[rear[1]++][1]=(Node(to,s.step+1,2,front[1])); se[1].insert(to);//printf("%d\n",to); } to=((LL)s.num+p-1)%p; if(se[1].find(to)==se[1].end()){ dis[1][to]=rear[1]; q[rear[1]++][1]=(Node(to,s.step+1,1,front[1])); se[1].insert(to);//printf("%d\n",to); } to=get_inv((LL)s.num,p); if(se[1].find(to)==se[1].end()){ dis[1][to]=rear[1]; q[rear[1]++][1]=(Node(to,s.step+1,3,front[1])); se[1].insert(to);//printf("%d\n",to); } front[1]++; } } } int main(){ scanf("%d%d%lld",&u,&v,&p); bfs(u,v); return ;
}
标签:复杂 set front define clu sqrt map out lse
原文地址:https://www.cnblogs.com/a-blog-of-taojiayi-2003/p/11267348.html