pta l3-7(天梯地图)

本文介绍了一种使用两次Dijkstra算法解决寻找两点间最快且最短路径的问题。第一次Dijkstra算法考虑时间和距离,第二次则考虑距离和经过节点数,确保找到最优路径。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:https://pintia.cn/problem-sets/994805046380707840/problems/994805051153825792

题意:给定n个地点,m条边以及边的信息,给出起点s,终点d,求s到d的最快距离,不唯一时取距离最短的,还要求s到d的最短距离,不唯一时取经过结点数最少的,若这两条路线重合,输出一条即可。

思路:两次dijkstra算法,第一次的两个维度是时间tim,距离len,用pre1记录路径; 第二次的两个维度是距离len,经过结点数num,用pre2记录路径。为了便于比较两条路径是否一致,可将其存在vector中,直接用‘==’判断即可,然后按照要求输出(代码看着挺长,其实两次dijkstra差不多)。

AC代码:

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 
  4 const int maxn=505;
  5 const int inf=0x3f3f3f3f;
  6 int n,m,s,d;
  7 int a[maxn][maxn],b[maxn][maxn],tim[maxn],len[maxn],num[maxn],vis1[maxn],vis2[maxn],pre1[maxn],pre2[maxn];
  8 vector<int> v1,v2;
  9 
 10 void dijkstra1(){
 11     len[s]=tim[s]=0;
 12     for(int i=0;i<n;++i){
 13         int k,Min=inf;
 14         for(int j=0;j<n;++j)
 15             if(!vis1[j]&&tim[j]<Min)
 16                 k=j,Min=tim[j];
 17         if(Min==inf) break;
 18         vis1[k]=1;
 19         for(int j=0;j<n;++j)
 20             if(!vis1[j]&&tim[j]>tim[k]+b[k][j]){
 21                 tim[j]=tim[k]+b[k][j];
 22                 len[j]=len[k]+a[k][j];
 23                 pre1[j]=k;
 24             }
 25             else if(!vis1[j]&&tim[j]==tim[k]+b[k][j]&&len[j]>len[k]+a[k][j]){
 26                 len[j]=len[k]+a[k][j];
 27                 pre1[j]=k;
 28             }
 29     }
 30 }
 31 
 32 void dijkstra2(){
 33     len[s]=0,num[s]=1,pre2[s]=-1;
 34     for(int i=0;i<n;++i){
 35         int k,Min=inf;
 36         for(int j=0;j<n;++j)
 37             if(!vis2[j]&&len[j]<Min)
 38                 k=j,Min=len[j];
 39         if(Min==inf) break;
 40         vis2[k]=1;
 41         for(int j=0;j<n;++j)
 42             if(!vis2[j]&&len[j]>len[k]+a[k][j]){
 43                 len[j]=len[k]+a[k][j];
 44                 num[j]=num[k]+1;
 45                 pre2[j]=k;
 46             }
 47             else if(!vis2[j]&&len[j]==len[k]+a[k][j]&&num[j]>num[k]+1){
 48                 num[j]=num[k]+1;
 49                 pre2[j]=k;
 50             }
 51     }
 52 }
 53 
 54 void getv1(){
 55     int p=d;
 56     while(p!=-1){
 57         v1.push_back(p);
 58         p=pre1[p];
 59     }
 60 }
 61 
 62 void getv2(){
 63     int p=d;
 64     while(p!=-1){
 65         v2.push_back(p);
 66         p=pre2[p];
 67     }
 68 }
 69 
 70 int main()
 71 {
 72     scanf("%d%d",&n,&m);
 73     memset(a,0x3f,sizeof(a));
 74     memset(b,0x3f,sizeof(b));
 75     for(int i=0;i<n;++i)
 76         tim[i]=len[i]=inf,pre1[i]=-1;
 77     for(int i=0;i<m;++i){
 78         int t1,t2,flag,l,t;
 79         scanf("%d%d%d%d%d",&t1,&t2,&flag,&l,&t);
 80         a[t1][t2]=l,b[t1][t2]=t;
 81         if(!flag)
 82             a[t2][t1]=l,b[t2][t1]=t;
 83     }
 84     scanf("%d%d",&s,&d);
 85     dijkstra1();
 86     getv1();
 87     for(int i=0;i<n;++i)
 88         len[i]=num[i]=inf,pre2[i]=-1;
 89     dijkstra2();
 90     getv2();
 91     if(v1==v2){
 92         printf("Time = %d; Distance = %d: %d",tim[d],len[d],s);
 93         for(int i=v1.size()-2;i>=0;--i)
 94             printf(" => %d",v1[i]);
 95     }
 96     else{
 97         printf("Time = %d: %d",tim[d],s);
 98         for(int i=v1.size()-2;i>=0;--i)
 99             printf(" => %d",v1[i]);
100         printf("\n");
101         printf("Distance = %d: %d",len[d],s);
102         for(int i=v2.size()-2;i>=0;--i)
103             printf(" => %d",v2[i]);
104     }
105     return 0;
106 }

 

转载于:https://www.cnblogs.com/FrankChen831X/p/10601586.html

### Java 实现二叉搜索树结构 在Java中实现二叉搜索树(BST),可以定义一个`TreeNode`类来表示树中的节点,并创建相应的操作方法,如插入、删除和查找。以下是基于给定需求的一个简单实现。 #### TreeNode 类定义 ```java class TreeNode { int key; TreeNode left, right; public TreeNode(int item) { key = item; left = right = null; } } ``` 此部分代码定义了一个名为 `TreeNode` 的类[^1],它拥有三个属性:键值 (`key`) 和指向左孩子与右孩子的指针(`left`, `right`)。构造函数初始化这些成员变量。 #### BinarySearchTree 类定义及其基本功能 ```java public class BinarySearchTree { private TreeNode root; // 构造器 初始化为空树 BinarySearchTree() { root = null; } // 插入新结点的方法 void insert(int key) { root = insertRec(root, key); } /* 递归辅助函数用于插入 */ TreeNode insertRec(TreeNode root, int key) { /* 如果树是空的,则返回新的节点作为根*/ if (root == null) { root = new TreeNode(key); return root; } // 否则按照 BST 属性决定位置并继续向下寻找合适的位置 if (key < root.key) root.left = insertRec(root.left, key); else if (key > root.key) root.right = insertRec(root.right, key); // 返回未改变的指针 return root; } // 查找最小值的方法 void minValueNode() { TreeNode current = root; /* 循环向左移动直到找到最左边叶子 */ while (current.left != null) current = current.left; System.out.println("The minimum value is " + current.key); } // 中序遍历打印所有元素 void inorderTraversal() { inorderHelper(root); } // 辅助函数完成实际工作 void inorderHelper(TreeNode root) { if (root != null) { inorderHelper(root.left); // 遍历左子树 System.out.print(root.key + " "); // 访问根部 inorderHelper(root.right); // 遍历右子树 } } } ``` 上述实现了二叉搜索树的主要特性,包括但不限于插入新项以及按升序显示所有条目。通过调用`insert()` 方法可将数据加入到适当位置;而`inorderTraversal()` 则展示了如何利用中序遍历来获取排序后的列表形式输出[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值