POJ 3126 Prime Path 解题报告(BFS & 双向BFS)
题目大意:给定一个4位素数,一个目标4位素数。每次变换一位,保证变换后依然是素数,求变换到目标素数的最小步数。
解题报告:直接用最短路。
枚举1000-10000所有素数,如果素数A交换一位可以得到素数B,则在AB间加入一条长度为1的双向边。
则题中所求的便是从起点到终点的最短路。使用Dijkstra或SPFA皆可。
当然,纯粹的BFS也是可以的。
用Dijkstra算法A了题目之后,看了一下Discuss,发现了一个新名词,双向BFS。
即从起点和终点同时进行BFS,相遇则求得最短路。
借鉴了思想,自己动手实现了代码。原本以为双向比单向快一倍而已,其实远远不止。
笔者用30W数据分别测试了单向和双向。环境为CodeBlock+MinGW4.7,Debug,双向时间为8.618s,而单向为惊人的139.989s!
简单思考了一下,也还是合理的。单向每次的增长是指数级的,而双向的指数只有单向的一半,优化程度相当高。
好了,贴代码~首先是双向BFS的Dijkstra:
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std; const int maxn=;
int prime[maxn];
const int maxV=;
int first[maxV],vv[maxV*maxV],nxt[maxV*maxV];
int num[maxV];
bool vis[][maxV];
int index; bool check(int a,int b)
{
int k=a-b;
if(k%==)
return true;
if(k< && k%== && a/==b/)
return true;
if(k< && k%== && a/==b/)
return true;
if(a/==b/)
return true;
return false;
} void calPrime()
{
for(int i=;i<maxn;i++) if(!prime[i])
{
for(int j=*i;j<maxn;j+=i)
prime[j]=true;
if(i>= && i<)
{
num[++index]=i;
prime[i]=index;
}
} int e=;
memset(first,,sizeof(first));
for(int i=;i<=index;i++)
for(int j=i+;j<=index;j++) if(check(num[j],num[i]))
{
nxt[e]=first[i],vv[e]=j,first[i]=e++;
nxt[e]=first[j],vv[e]=i,first[j]=e++;
}
} struct Node
{
int node;
int level;
bool operator<(const Node& cmp) const
{
return level>cmp.level;
}
} p,q; int Dijkstra(int sta,int end)
{
if(sta==end)
return ; memset(vis,,sizeof(vis)); sta=prime[sta];
end=prime[end]; priority_queue<Node> pq[];
p.node=sta;
p.level=;
vis[][p.node]=true;
pq[].push(p); p.node=end;
p.level=;
vis[][p.node]=true;
pq[].push(p); for(int i=; !pq[].empty() && !pq[].empty() ;i++)
{
int sel=;
if(pq[].size()>pq[].size())
sel++;
int level=pq[sel].top().level;
while(!pq[sel].empty())
{
p=pq[sel].top();
if(p.level!=level) //先判断,否则会pop掉丢失情况
break;
pq[sel].pop(); for(int e=first[p.node];e;e=nxt[e])
{
if(vis[-sel][vv[e]])
return i+;
if(!vis[sel][vv[e]])
{
q.level=p.level+;
q.node=vv[e];
vis[sel][vv[e]]=true;
pq[sel].push(q);
}
}
}
} return -;
} int main()
{
calPrime(); int T;
scanf("%d",&T);
while(T--)
{
int sta,end;
scanf("%d%d",&sta,&end);
int ans=Dijkstra(sta,end);
if(ans==-)
printf("Impossible\n");
else
printf("%d\n",ans);
}
}
然后是单向的BFS+Dijkstra:
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std; const int maxn=;
int prime[maxn];
const int maxV=;
int first[maxV],vv[maxV*maxV],nxt[maxV*maxV];
int num[maxV];
bool vis[maxV];
int index;
int count; bool check(int a,int b)
{
int k=a-b;
if(k%==)
return true;
if(k< && k%== && a/==b/)
return true;
if(k< && k%== && a/==b/)
return true;
if(a/==b/)
return true;
return false;
} void calPrime()
{
for(int i=;i<maxn;i++) if(!prime[i])
{
for(int j=*i;j<maxn;j+=i)
prime[j]=true;
if(i>= && i<)
{
num[++index]=i;
prime[i]=index;
}
} int e=;
memset(first,,sizeof(first));
for(int i=;i<=index;i++)
for(int j=i+;j<=index;j++) if(check(num[j],num[i]))
{
nxt[e]=first[i],vv[e]=j,first[i]=e++;
nxt[e]=first[j],vv[e]=i,first[j]=e++;
}
} struct Node
{
int k;
int w;
bool operator<(const Node& cmp) const
{
return w>cmp.w;
}
} p,q; int Dijkstra(int sta,int end)
{
memset(vis,,sizeof(vis));
end=prime[end]; p.k=prime[sta];
p.w=;
vis[p.k]=true; priority_queue<Node> pq;
pq.push(p); while(!pq.empty())
{
p=pq.top();
pq.pop(); if(p.k==end)
return p.w; for(int e=first[p.k];e;e=nxt[e]) if(!vis[vv[e]])
{
q.k=vv[e];
q.w=p.w+;
vis[q.k]=true;
pq.push(q);
}
}
return -;
} int main()
{
calPrime(); int T;
scanf("%d",&T);
while(T--)
{
int sta,end;
scanf("%d%d",&sta,&end);
int ans=Dijkstra(sta,end);
if(ans==-)
printf("Impossible\n");
else
printf("%d\n",ans);
}
}
测试数据我放在了百度云,有兴趣可以下载下来试一下:http://pan.baidu.com/share/link?shareid=4217669741&uk=2804348991
POJ 3126 Prime Path 解题报告(BFS & 双向BFS)的更多相关文章
- 双向广搜 POJ 3126 Prime Path
POJ 3126 Prime Path Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 16204 Accepted ...
- BFS POJ 3126 Prime Path
题目传送门 /* 题意:从一个数到另外一个数,每次改变一个数字,且每次是素数 BFS:先预处理1000到9999的素数,简单BFS一下.我没输出Impossible都AC,数据有点弱 */ /**** ...
- POJ 3126 Prime Path(素数路径)
POJ 3126 Prime Path(素数路径) Time Limit: 1000MS Memory Limit: 65536K Description - 题目描述 The minister ...
- poj 3126 Prime Path bfs
题目链接:http://poj.org/problem?id=3126 Prime Path Time Limit: 1000MS Memory Limit: 65536K Total Submi ...
- POJ - 3126 - Prime Path(BFS)
Prime Path POJ - 3126 题意: 给出两个四位素数 a , b.然后从a开始,每次可以改变四位中的一位数字,变成 c,c 可以接着变,直到变成b为止.要求 c 必须是素数.求变换次数 ...
- POJ 3126 Prime Path 素数筛,bfs
题目: http://poj.org/problem?id=3126 困得不行了,没想到敲完一遍直接就A了,16ms,debug环节都没进行.人品啊. #include <stdio.h> ...
- POJ 3126 Prime Path(BFS 数字处理)
意甲冠军 给你两个4位质数a, b 每次你可以改变a个位数,但仍然需要素数的变化 乞讨a有多少次的能力,至少修改成b 基础的bfs 注意数的处理即可了 出队一个数 然后入队全部能够由这个素 ...
- (简单) POJ 3126 Prime Path,BFS。
Description The ministers of the cabinet were quite upset by the message from the Chief of Security ...
- POJ 3126 Prime Path【从一个素数变为另一个素数的最少步数/BFS】
Prime Path Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 26475 Accepted: 14555 Descript ...
随机推荐
- 07_例子讲解:rlCoachKin + rlCoachMdl
RL提供了2个相当简单的基于socket的虚拟化机器人,是socket服务端. rlCoachKin是用于D-H运动链(在rlkin\*xml中定义的). rlCoachMdl相当于任意几何的工具链. ...
- HDOJ1005 数列
Problem Description A number sequence is defined as follows:f(1) = 1, f(2) = 1, f(n) = (A * f(n - 1) ...
- [转载]浅析STL allocator
本文转载自水目沾博客:http://www.cnblogs.com/zhuwbox/p/3699977.html 向大师致敬 一般而言,我们习惯的 C++ 内存配置操作和释放操作是这样的: 1 c ...
- Delphi中的GetEnumName和GetEnumValue的使用方法
利用TypInfo单元的GetEnumName和GetEnumValue可以遍历任意枚举类型,并获取其名称和值.下面是示例Demo. uses TypInfo; ... procedure TForm ...
- 将TIBCO Host 实例注册为Windows服务
安装了TIBCO ActiveMatrix BPM及成功创建了ActiveMatrix Administrator 和 BPM Server后,每次都要手动启动tibcohost,比较麻烦,实际上TI ...
- hadoop基本命令1
(大讲台——国内首个it在线混合式自适应学习平台,轻量级的高薪就业和技能提升解决方案) 1.列出所有Hadoop Shell支持的命令$ bin/hadoop fs -help2.显示关于某个命令的详 ...
- SLua
安装 1.下载最新版,将Assets目录里的所有内容复制到工程中,对于最终产品,可以删除例子,文档等内容,如果是开发阶段则无所谓. 2.等待unity编译完毕,如果一切顺利的话,将出现SLua菜单,点 ...
- 关于JS中的apply()与call()使用方法与区别
Js apply方法详解我在一开始看到javascript的函数apply和call时,非常的模糊,看也看不懂,最近在网上看到一些文章对apply方法和call的一些示例,总算是看的有点眉目了,在这里 ...
- ios短信和电话--参考
调用打电话功能 [[UIApplicationsharedApplication] openURL:[NSURL URLWithString:@"tel://10086"]]; 调 ...
- 在安装MySQL Workbentch的时候出现如下问题,已经解决。
mysql workbench cannot be executed from a path that contains non-ASCII characters. this problem is i ...