题解
- 这题是无向无权图的最短路径问题,无权图的最短路径用BFS求解就好了,没必要用Dijkstra。
题目
问题 B: 六度空间(queue)
时间限制: 1 Sec 内存限制: 128 MB
提交: 122 解决: 67
[提交][状态][讨论版]
题目描述
六度空间理论指出:你和任何一个陌生人之间所间隔的人不会超过六个,也就是说,最多通过6个中间人你就能够认识任何一个陌生人。验证这一理论需要大数据量。现在,只需要计算任意两个人通过多少个中间人能互相认识。
假设有 n 个人,他们的编号为 1~n,其中有一些人相互认识,现在 x 想通过一些中间人认识 y(如果 a 认识 b,b 认识 c,那么 a 可以通过 b 来认识 c),编程求出 x 最少需要通过多少人才能认识 y。
思路:x入队列。只有队列非空,取队头元素,队头元素为y,结束。否则,访问队头元素所在的行,他认识的人还未入对,则入队。因还有通过多少人认识,入队除元素外,加层次。x层次为0。x认识的为1,再下一次为2。
该题是从x出发,一层层找他认识的人,直到找到y,或队列空,即找不到y。
输入
第一行,测试次数t
每组测试数据格式如下:
第 1 行 3 个整数 n、x、y,2≤n≤100;
接下来的 n 行是一个 n×n 的邻接矩阵,
a[i][j]=1 表示 i 认识 j,a[i][j]=0 表示不认识。
保证 i=j 时,a[i][j]=0,并且 a[i][j]=a[j][i]。
输出
每组测试数据,输出一行,输出 x 认识 y 最少需要通过的人数。如果x通过中间的人不能认识y,输出no。
样例输入
2
5 1 5
0 1 0 0 0
1 0 1 1 0
0 1 0 1 0
0 1 1 0 1
0 0 0 1 0
5 4 5
0 1 0 1 0
1 0 1 0 0
0 1 0 0 1
1 0 0 0 0
0 0 1 0 0
样例输出
2
3
代码块
#include <iostream>
#include <queue>
using namespace std;
typedef struct{
int vertex;
int step;
} Box;
class Graph
{
int vexnum;
int **matrix;
int *flag;
int startvex;
int endvex;
public:
Graph(int num, int num1, int num2);
~Graph();
void BFSTraverse();
};
Graph::Graph(int num, int num1, int num2)
{
vexnum = num;
startvex = num1-1;
endvex = num2-1;
flag = new int[vexnum];
matrix = new int*[vexnum];
for(int i=0; i<vexnum; i++)
{
flag[i] = 0;
matrix[i] = new int[vexnum];
for(int j=0; j<vexnum; j++)
cin>>matrix[i][j];
}
}
Graph::~Graph()
{
delete []flag;
for(int i=0; i<vexnum; i++)
delete []matrix[i];
delete []matrix;
}
void Graph::BFSTraverse()
{
Box temp;
temp.vertex = startvex;
temp.step = 0;
queue<Box> q;
q.push(temp);
flag[temp.vertex] = 1;
while(!q.empty())
{
temp = q.front();
q.pop();
int vertex = temp.vertex;
int step = temp.step;
for(int i=0; i<vexnum; i++)
{
if(matrix[vertex][i] && !flag[i])
{
temp.vertex = i;
temp.step = step+1;
q.push(temp);
flag[i] = 1;
if(i==endvex)
{
cout<<step<<endl;
return;
}
}
}
}
cout<<"no"<<endl;
}
int main(void)
{
int t;
cin>>t;
while(t--)
{
int num, num1, num2;
cin>>num>>num1>>num2;
Graph myGraph(num, num1, num2);
myGraph.BFSTraverse();
}
}