您的当前位置:首页正文

2024年十五届蓝桥杯大学b组第二场--狡兔k窟(求支援)

来源:九壹网

题目描述
一只兔子名叫小蓝,它异常狡猾,在土中挖了若干洞窟并且设置了很多出入口来应对紧急情况。它一共有 n 个通往地面的出入口,在地面上这 n 个出入口之间由 n − 1 条长度为 1 的双向通路连成一个连通图。第 i 个出入口属于第 ci个洞窟,因此小蓝可以在任意一个属于 ci 的出入口从地面进入洞窟然后从任意一个属于 ci 的出入口跑出到达地面。
小蓝提出了 m 个逃跑路线,第 i 个路线希望从出入口 si 逃往 ti ,它希望在逃跑的过程中在地面上跑动的距离尽可能短,请为每条路线计算逃跑时在地面上跑动的最短距离。
输入格式
输入的第一行包含两个正整数 n, m ,用一个空格分隔。
第二行包含 n 个正整数 c1, c2, · · · , cn ,相邻整数之间使用一个空格分隔。
接下来 n − 1 行,第 i 行包含两个整数 ui, vi ,用一个空格分隔,表示地面上的一条通路连接 ui 和 vi 。
接下来 m 行,第 i 行包含两个整数 si, ti ,用一个空格分隔。
输出格式
输出 m 行,每行包含一个整数,依次表示每个询问的答案。
样例输入
复制
6 3
1 3 2 1 2 3
1 2
1 3
2 4
2 5
3 6
2 6
3 2
4 3
样例输出
复制
0
1
1

对于 20% 的评测用例,1 ≤ n, m, ci ≤ 100 ;
对于所有评测用例,1 ≤ n, m, ci ≤ 5000 ,1 ≤ ui, vi, si, ti ≤ n 。

因为路径是无权的(都为1),所以我的个人思路以起点窟为根,找出终点窟第一次出现的深度,即为最短路径

窟的的相关信息用结构体储存,查找用bfs配合队列       C语言代码

#include<stdio.h>
#include<string.h>
#define MAX 5005

typedef struct hole{
    int f[MAX];         //储存与此窟有通道的窟 
    int k;              //储存个数 
}A;

int q[MAX];          //用于构造队列 
int v[MAX];          //用于表示是否访问 
int map[MAX][MAX];   //储存最小路径 
int index=0,low=0,max;  //index代表队列头的下表,low代表队列尾下表 
A dis[MAX];             //储存窟 

void bfs(int x,int y){          
    if(dis[q[index]].k){
        for(int i=0;i<dis[q[index]].k;i++){    //搜索,录入新元素(队列) 
            int r=dis[q[index]].f[i];
            if(!v[r]){
                low++;
                q[low]=r;
                if(map[x][r]==0){            //根据树的深度录入最小路径 
                    map[x][r]=map[x][q[index]]+1;
                }
                v[r]=1;
            }
        }
        if(map[x][y]){
            return ;
        }
    index++;               //抛弃头元素 
    bfs(x,y);
    }
}
int main(){
    
    int n,m;
    scanf("%d%d",&n,&m);
    int d[n+1];
    for(int i=1;i<=n;i++){
        scanf("%d",&d[i]);
        dis[d[i]].k=0;
    }
    for(int i=0;i<n-1;i++){                 //录入窟的信息 
        int ori,des;
        scanf("%d%d",&ori,&des);
        int index1=dis[d[ori]].k;
        int index2=dis[d[des]].k;
        dis[d[ori]].f[index1]=d[des];
        dis[d[des]].f[index2]=d[ori];
        dis[d[ori]].k++;
        dis[d[des]].k++;
        map[d[ori]][d[des]]=1;
        map[d[des]][d[ori]]=1;
    }
    for(int i=0;i<m;i++){
        int ori,des;
        scanf("%d%d",&ori,&des);
        if(d[ori]==d[des]){               
            printf("0\n");
        }else if(map[d[ori]][d[des]]){        //只有有值时才输出 
            printf("%d\n",map[d[ori]][d[des]]);
        }else if(map[d[des]][d[ori]]){
            printf("%d\n",map[d[des]][d[ori]]);
        }else{
            memset(v,0,sizeof(v));          //初始化,并进行搜索 
            index=0;
            low=0;
            v[d[ori]]=1;
            q[0]=d[ori];
            bfs(d[ori],d[des]);
                printf("%d\n",map[d[ori]][d[des]]);
        }
    }
    return 0;
}

然而是检测是错的,所以大佬们看出问题的能帮我指正一下吗?

因篇幅问题不能全部显示,请点此查看更多更全内容

Top