【转】POJ-2243-Knight Moves:DFS || BFS || Floyd 求最短路
DFS
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int knight[8][8];// 各点到起点的最短距离
int x[8]={-2, -1, 1, 2, -2, -1, 1, 2};
int y[8]={-1, -2, -2, -1, 1, 2, 2, 1};
void DFS(int i, int j, int dis)
{
if(i<0||i>7||j<0||j>7||knight[i][j]<=dis)
return;
knight[i][j]=dis;
for(int k=0; k<8; k++)
DFS(i+x[k], j+y[k], dis+1);
}
int main()
{
char S1[10], S2[10];
while(cin>>S1>>S2)
{
memset(knight, 10, sizeof(knight));// 初始化距离较大 DFS时再更新
DFS(S1[0]-'a', S1[1]-'1', 0);
printf("To get from %s to %s takes %d knight moves.\n", S1, S2, knight[S2[0]-'a'][S2[1]-'1']);
}
return 0;
}
BFS
#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
int x[8]={-2, -1, 1, 2, -2, -1, 1, 2};
int y[8]={-1, -2, -2, -1, 1, 2, 2, 1};
struct point
{
int x, y;
int dis;
};
int main()
{
queue<point>que;
char S1[10], S2[10];
while(cin>>S1>>S2)
{
while(!que.empty())
que.pop();
point p;
p.x=S1[0]-'a';
p.y=S1[1]-'1';
p.dis=0;
que.push(p);
while(!que.empty())
{
p = que.front();
que.pop();
if(p.x==S2[0]-'a' && p.y==S2[1]-'1')
break;
point tmp;
for(int i=0; i<8; i++)
{
tmp.x=p.x+x[i];
tmp.y=p.y+y[i];
tmp.dis=p.dis+1;
if(tmp.x<0 || tmp.x>7 || tmp.y<0 || tmp.y>7)
continue;
que.push(tmp);
}
}
printf("To get from %s to %s takes %d knight moves.\n", S1, S2, p.dis);
}
return 0;
}
Floyd
算法详解请点这里
应用于改题的思路:由于棋盘很小,而输入数据可能很大,则可以想到先打表存储每点到各点的最短路径,这样对于所有输入查表输出即可。
当然前提是从每一点出发可以到达任一点(题中有提到)
相对于DFS和BFS来说 Floyd的时间复杂度最小
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
using namespace std;
void Floyd(int k[][64])
{
int dx, dy;// 两点间相对距离
for(int i=0; i<64; k[i][i]=0,i++)
for(int j=0; j<64; j++){
dx=abs(i/8-j/8);
dy=abs(i%8-j%8);
if(dx==1&&dy==2 || dx==2&&dy==1)// 骑士一步的距离
k[i][j]=k[j][i]=1;
}
for(int l=0; l<64; l++)
for(int i=0; i<64; i++)
for(int j=0; j<64; j++){
if(k[i][l]+k[l][j]<k[i][j])
k[i][j]=k[i][l]+k[l][j];
}
}
int main()
{
char S1[10], S2[10];
int knight[64][64];// 棋盘中每点到其余给点的距离 以骑士的步长为单位
memset(knight, 10, sizeof(knight));//初始化为无穷
Floyd(knight);// 打表 存储
while(cin>>S1>>S2)
{
int x=(S1[0]-'a')*8+S1[1]-'1';
int y=(S2[0]-'a')*8+S2[1]-'1';
// 直接查表 打印结果
printf("To get from %s to %s takes %d knight moves.\n", S1, S2, knight[x][y]);
}
return 0;
}
总结:Floyd算法适合稠密图 即图小数据量大 而BFS适合稀疏图 即图大数据量小。

浙公网安备 33010602011771号