题目:(机房)
题目描述(13届 C&C+G题)
解题思路:
这道题目可以看作在一个无向图中查找两点之间的最短路径。题目中的 n 台电脑和 n−1 根网线形成了一棵树,树是一个特殊的无向图,因此我们可以利用 广度优先搜索(BFS) 来求解最短路径问题。
-
建图:
-
通过输入的 n−1 对电脑连接关系构建邻接表表示的无向图。
-
-
最短路径搜索:
-
利用 BFS,从起点开始逐层扩展,找到终点时输出步数。
-
由于树的性质,BFS的第一条找到的路径一定是最短路径。
-
-
多个查询的处理:
-
每次查询直接用 BFS 求解从起点到终点的最短路径。
-
代码实现(C语言):
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int road(int start,int end,int dex,int num,int bef,int n);
int map[10000][10000];
int dey[10000];
int main()
{
int n,m;
scanf("%d",&n);
scanf("%d",&m);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(i==j)
{
map[i][j]=1;
}
else
{
map[i][j]=0;
}
}
dey[i]=-1;
}
for(int i=1;i<=n-1;i++)
{
int a;
int b;
scanf("%d",&a);
scanf("%d",&b);
map[a][b]=1;
map[b][a]=1;
}
int q[m+1][2];
for(int i=1;i<=m;i++)
{
scanf("%d",&q[i][0]);
scanf("%d",&q[i][1]);
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
dey[i]=dey[i]+map[i][j];
}
}
for(int i=1;i<=m;i++)
{
printf("%d\n",road(q[i][0],q[i][1],q[i][0],0,-1,n));
}
return 0;
}
int road(int start,int end,int dex,int num,int bef,int n)
{
//printf("%d to %d have %d\n",bef,dex,num);
if(dex==end)
{
return num+dey[dex];
}
else
{
int new_num=num+dey[dex];
int lin=-100;
int e=0;
for(int i=1;i<=n;i++)
{
if(i!=dex && map[i][dex]==1 && i!=bef)
{
lin=fmax(lin,road(start,end,i,new_num,dex,n));
e=e+1;
}
}
if(e==0)
{
return -100;
}
else
{
return lin;
}
}
}
得到运行结果:
代码分析:
-
初始化部分
-
通过输入节点数
n
和边数m
,创建一个邻接矩阵来表示图,初始化每个节点的度数为-1。 -
将图的边输入,并更新邻接矩阵。
-
-
查询输入部分
-
输入多个查询,每个查询要求计算从一个节点到另一个节点的路径代价。
-
-
计算每个节点的度数
-
遍历邻接矩阵,计算每个节点的度数,并将其存储在一个数组中。
-
-
计算路径代价的递归函数
-
使用深度优先搜索(DFS)递归遍历路径,如果当前节点是终点,则返回路径代价;否则,继续递归遍历与当前节点相邻的未访问节点。
-
每到一个节点,路径代价会累加该节点的度数。
-
-
输出查询结果
-
对每个查询,调用递归函数计算路径代价,并输出结果。
-
难度分析
⭐️⭐️⭐️⭐️⭐️
总结
-
图的表示:采用邻接矩阵和度数数组表示图。
-
深度优先搜索(DFS):使用递归方法遍历路径并计算路径代价。
-
路径代价计算:路径代价由路径上经过的所有节点的度数之和来确定。