第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-5 算法训练 最短路

简介: 第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-5 算法训练 最短路

第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-5 算法训练 最短路


前言

       最近的一些文章都可能会很碎,写到哪里是哪里,过一阵子会具体的整理一遍,这里其它的类型题先往后排一排,因为蓝桥最后考的也就是对题目逻辑的理解能力,也就是dp分析能力了,所以就主要目标定在这里,最近的题目会很散,很多,基本上都是网罗全网的一些dp练习题进行二次训练,准备比赛的学生底子薄的先不建议看啊,当然,脑子快的例外,可以直接跳过之前的一切直接来看即可,只需要你在高中的时候数学成绩还可以那就没啥问题,其实,dp就是规律总结,我们只需要推导出对应题目的数学规律就可以直接操作,可能是一维数组,也可能是二维数组,总体来看二维数组的较多,但是如果能降为的话建议降为,因为如果降为起来你看看时间复杂度就知道咋回事了,那么在这里祝大家能无序的各种看明白,争取能帮助到大家。


算法训练 最短路

资源限制

内存限制:256.0MB   C/C++时间限制:1.0s   Java时间限制:3.0s   Python时间限制:5.0s

问题描述

给定一个n个顶点,m条边的有向图(其中某些边权可能为负,但保证没有负环)。请你计算从1号点到其他点的最短路(顶点从1到n编号)。

输入格式

第一行两个整数n, m。

接下来的m行,每行有三个整数u, v, l,表示u到v有一条长度为l的边。

输出格式

共n-1行,第i行表示1号点到i+1号点的最短路。

样例输入

3 3

1 2 -1

2 3 -1

3 1 2

样例输出

-1

-2

数据规模与约定

对于10%的数据,n = 2,m = 2。

对于30%的数据,n <= 5,m <= 10。

对于100%的数据,1 <= n <= 20000,1 <= m <= 200000,-10000 <= l <= 10000,保证从任意顶点都能到达其他所有顶点。

题解,最短路径的问题相对来说我们就可以直接套搜索了,队列操作,我们可以选择广搜bfs。

C语言

#include<stdio.h>
int dis[20005],u[200005],v[200005],w[200005];
int main()
{
  int m,n,i,k,check;
  int inf=99999999;
  scanf("%d%d",&n,&m);
  for(i=1;i<=m;i++)
    scanf("%d%d%d",&u[i],&v[i],&w[i]);
  for(i=1;i<=n;i++)
    dis[i]=inf;
  dis[1]=0;
  for(k=1;k<=n-1;k++){
    check=0;
    for(i=1;i<=m;i++){
      if(dis[v[i]]>dis[u[i]]+w[i]){
        dis[v[i]]=dis[u[i]]+w[i];
        check=1;}
      }
    if(check==0)
      break;}
  for(i=2;i<=n;i++)
    printf("%d\n",dis[i]);
  return 0;
}

C++语言

#include<stdio.h>  
 #include<string.h>  
 #define inf 100000  
 struct In{  
     int e;  
     int w;  
     int next;  
 }map[200010];  
 int dis[20010],Q[20010];  
 int vis[20010],head[20010];  
 void SPFA(int n){  
     int i,j,front,rear,temp;  
     for(i=1;i<=n;i++){  
         dis[i]=inf;  
     }  
     dis[1]=0;vis[1]=1;  
     front=0;rear=1;  
     Q[front]=1;  
     while(front<rear){  
         temp=Q[front++];  
         vis[temp]=0;  
         j=head[temp];  
         while(j>0){  
             if(dis[map[j].e]>map[j].w+dis[temp]){  
                 dis[map[j].e]=map[j].w+dis[temp];  
                 if(!vis[map[j].e]){  
                     Q[rear++]=map[j].e;  
                     vis[map[j].e]=1;   
                 }  
             }  
             j=map[j].next;  
         }  
     }  
 }  
 int main(){  
     int n,m,i,j,a,b,val;  
     while(~scanf("%d%d",&n,&m)){  
         memset(Q,0,sizeof(Q));  
         memset(head,0,sizeof(head));  
         memset(vis,0,sizeof(vis));  
         for(i=1;i<=m;i++){  
             scanf("%d%d%d",&a,&b,&val);  
             map[i].e=b;  
             map[i].w=val;  
             map[i].next=head[a];  
             head[a]=i;  
         }  
         SPFA(n);  
         for(i=2;i<=n;i++){  
             printf("%d\n",dis[i]);  
         }  
     }  
     return 0;  
 }

Java语言

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.List;
import java.util.Queue;
import java.util.Scanner;
public class Main {
  static int leng[];
  public static void main(String[] args){
    Scanner sc = new Scanner(System.in);
    int n = sc.nextInt();
    int m = sc.nextInt();
    List<node> list[] = new ArrayList[n];// 存储路径
    for (int i = 0; i < n; i++)// 声明
    {
      list[i] = new ArrayList<node>();
    }
    leng = new int[n];
    boolean jud[] = new boolean[n];// 判断是否在队列内
    for (int i = 1; i < n; i++) {
      leng[i] = Integer.MAX_VALUE;
    } // 初始最长均为max
    for (int i = 0; i < m; i++) {
      int u = sc.nextInt();
      int v = sc.nextInt();
      int l = sc.nextInt();
      list[u - 1].add(new node(v - 1, l));
    }
    Queue<Integer> q1 = new ArrayDeque<Integer>();
    q1.add(0);// 第一个
    while (!q1.isEmpty()) {
      int x = q1.poll();
      jud[x] = false;
      for (int i = 0; i < list[x].size(); i++)// 遍历
      {
        int index = list[x].get(i).x;// x邻居该节点的编号
        int length = list[x].get(i).leng;// x到这个邻居的距离
        if (leng[index] > leng[x] + length) {
          leng[index] = leng[x] + length;
          if (!jud[index])// 队列中没有该点
          {
            q1.add(index);
            jud[index] = true;
          }
        }
      }
    }
    for (int i = 1; i < n; i++) {
      System.out.println(leng[i]);
    }
  }
  static class node {
    int x;
    int leng;
    public node(int x, int leng) {
      this.x = x;
      this.leng = leng;
    }
  }
}

Python语言

队列的广搜,代码看着不是很多,其实复杂度不低。

n,m=map(int,input().split())
g=[dict() for i in range(n+1)]
for i in range(m):
    u,v,l=map(int,input().split())
    g[u][v]=l
queue=[1]
visited=[True if i==1 else False for i in range(n+2)]
inf=1000000000
dist=[0 if i==1 else inf for i in range(n+2)]
while queue!=[]:
    rhs=queue.pop(0)
    visited[rhs]=False
    dicts=g[rhs]
    if dicts!={}:
        for key,value in dicts.items():
            if dist[key]>dist[rhs]+value:
                dist[key]=dist[rhs]+value
                if not visited[key]:
                    visited[key]=True
                    queue.append(key)
for i in range(2,n+1):
    print(dist[i])

总结

最短路问题在蓝桥杯中出现的频次还是非常高的,我们需要根据对应的题目做出搜索的选择,但是一般最短路都是广搜。

没有什么不付出就能拿到的结果,我们都是在负重前行,最终结果与自身先天的脑力有一定的关系,但是还是有很大一部分看自己后天的努力,其实从报名到比赛也就5个月左右,真正刷题的事件也就2个月,2个月回忆一下你真正的认真刷过题吗,如果你真的用尽所有的精力去努力了,那么我相信你最终的成绩一定会让你满意的,加油。


相关文章
|
1月前
|
人工智能 算法 Java
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-1005 数字游戏
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-1005 数字游戏
65 0
|
20天前
|
算法 C语言
数据结构和算法学习记录——栈和队列习题-用队列实现栈、用栈实现队列(核心思路、解题过程、完整题解)二
数据结构和算法学习记录——栈和队列习题-用队列实现栈、用栈实现队列(核心思路、解题过程、完整题解)二
17 2
|
5天前
|
人工智能 算法 搜索推荐
蓝桥杯宝藏排序题目算法(冒泡、选择、插入)
以下是内容的摘要: 本文介绍了三种排序算法:冒泡排序、选择排序和插入排序。冒泡排序通过不断交换相邻的逆序元素逐步排序,最坏情况下需要 O(n^2) 次比较。选择排序在每轮中找到剩余部分的最小元素并放到已排序序列的末尾,同样具有 O(n^2) 时间复杂度。插入排序则是将每个元素插入到已排序序列的正确位置,时间复杂度也是 O(n^2),但空间复杂度为 O(1)。
|
1月前
|
存储 算法 Java
蓝桥杯递归算法
蓝桥杯中的递归算法涉及将问题分解为子问题,通过函数自身调用来求解。优点是简洁易懂,但效率低且可能引发栈溢出。示例包括:数组求和、数的阶乘、斐波那契数列及最大公约数计算,以及字符串翻转。代码展示了各种递归场景的Java实现,如`f3`计算数组和,`f`求阶乘,`f1`计算斐波那契数,`f2`找最大公约数,和`f1`字符串反转。
26 1
|
1月前
|
算法 安全
死锁相关知识点以及银行家算法(解题详细步骤)
死锁相关知识点以及银行家算法(解题详细步骤)
32 2
|
20天前
|
算法 C语言
数据结构和算法学习记录——栈和队列习题-用队列实现栈、用栈实现队列(核心思路、解题过程、完整题解)一
数据结构和算法学习记录——栈和队列习题-用队列实现栈、用栈实现队列(核心思路、解题过程、完整题解)一
18 0
|
1月前
|
算法 安全 定位技术
【刷题】备战蓝桥杯 — dfs 算法
dfs算法在数据较小的情况下可以使用。 一定一定要确定好终止条件,避免栈溢出。 相应做好回溯,保证每次的遍历都是不一样的选择,避免少结果。 针对题目进行对应细节处理,有能力的话可以进行剪枝优化!!!
27 0
|
1月前
|
算法
讲课:拓扑排序、最短路算法
讲课:拓扑排序、最短路算法
|
1月前
|
算法 Java C语言
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-1007 印章
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-1007 印章
36 0
|
1月前
|
算法 Java C语言
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-1006 拿金币
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-1006 拿金币
35 0