蓝桥杯——星际旅行(bfs+邻接表优化)

一.题目

分析:只要是能传送过去并且传送次数不为0,就算可以到达,所以这里不能用dfs来,很明显的bfs算法,分层遍历,每一层会消耗一次传送次数,但是本题的数据过大,如果使用邻接矩阵来作为visited数组那么时间复杂度过高,只能通过部分测试用例

1.使用邻接矩阵遍历传送阵时间复杂度为O(n),假如有50万个星球,那么就需要遍历50万次

2.使用邻接表寻找传送阵时间复杂度为O(1)

二.代码

import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Scanner;
//1:无需package
//2: 类名必须Main, 不可修改

public class Main {
        public static double res;
        static class pair{
        int x;//当前星球
        int y;//剩余传送次数
        public pair(int x,int y)
        {
            this.x = x;
            this.y = y;
        }
    }
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int n = scan.nextInt();//n个星球
        int m = scan.nextInt();//m个双向传送门
        int q = scan.nextInt();//q个盲盒
        List<Integer>[] mark = new LinkedList[n+1];
        for (int i = 0; i <mark.length; i++) {
            mark[i] = new LinkedList<>();
        }
        for(int i = 1;i<=m;i++)
        {
            int x = scan.nextInt();
            int y = scan.nextInt();
            mark[x].add(y);//表示可以传送
            mark[y].add(x);
        }
        for(int i = 0;i<q;i++)
        {
            int x = scan.nextInt();//起始星球
            int y = scan.nextInt();//传送次数
            res += bfs(x,y,n,mark);
        }

        System.out.printf("%.2f",(double)res/q);
        scan.close();
    }
    public static int bfs(int index,int cnt,int n,List<Integer>[] mark)
    {
        Queue<pair> queue = new LinkedList<>();
        queue.add(new pair(index,cnt));
        int sum = 0;
        boolean[] map = new boolean[n+1];
        map[index] = true;//已经访问过该星球
        sum++;//表示访问当前星球
        while(!queue.isEmpty())
        {
            //需要分层遍历
            int tmp = queue.size();
            for(int i = 0;i<tmp;i++)
            {
                pair now = queue.poll();
                if(now.y<=0)  break;
                for(int j = 0;j<mark[now.x].size();j++)
                {
                    if(map[mark[now.x].get(j)]!=true)//表示可以访问入队
                    {
                        queue.add(new pair(mark[now.x].get(j),now.y-1));//到达需要消耗一次传送次数
                        map[mark[now.x].get(j)] = true;
                        sum++;
                    }
                }
            }
        }
        return sum;
    }
}

三.问题分析

1.第一次没有考虑到数据过大没有使用邻接表优化,注意使用集合数组前都需要为他们申请空间

2.多次写代码时写错变量,不够专注

### DFS 和 BFS 算法邻接表表示的图中的实现 #### 深度优先搜索 (DFS) 对于深度优先搜索,在邻接表表示的图中,可以通过递归或显式使用栈来实现。此方法适用于有向图和无向图。 ```c++ void DFS(ALGraph G, int v) { cout << "Visit node: " << v; visited[v] = true; EdgeNode* p = G.vertices[v].firstedge; while(p != NULL){ int w = p->adjvex; if(!visited[w]){ DFS(G,w); } p = p->next; } } ``` 为了初始化并调用上述函数: ```c++ void DFSTraverse(ALGraph &G) { memset(visited,false,sizeof(visited)); for(int i=0;i<G.vexnum;++i){ if (!visited[i]) { DFS(G,i); } } } ``` 这段代码展示了如何遍历整个图,即使存在不连通的部分[^1]。 #### 广度优先搜索 (BFS) 广度优先搜索则通常借助队列完成层次化探索的任务。同样地,这里也给出基于C++语言的一个简单例子: ```c++ void BFS(ALGraph G,int v) { queue<int> q; q.push(v); memset(visited,false,sizeof(visited)); visited[v]=true; while(!q.empty()){ int u=q.front(); q.pop(); cout<<"Visit node:"<<u<<endl; EdgeNode *p=G.vertices[u].firstedge; while(p!=NULL){ int w=p->adjvex; if(!visited[w]){ q.push(w); visited[w]=true; } p=p->next; } } } void BFSTraverse(ALGraph& G) { memset(visited,false,sizeof(visited)); for(int i=0;i<G.vexnum;++i){ if(!visited[i]){ BFS(G,i); } } } ``` 通过这种方式,可以逐层访问所有可达节点,并记录下它们被首次发现的时间戳等信息。 这两种算法都可用于解决多种实际问题,比如寻找最短路径、检测环路以及构建最小生成树等问题。当处理大规模数据集时,选择合适的策略尤为重要——DFS适合于求解具有较深嵌套结构的问题;而BFS更适合用于计算两点间距离或者查找最近公共祖先等情况。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值