今天在避风塘玩

昨天王洋从深圳回来了,今天晚上我们在天盛吃完饭来避风塘来完.我们玩的很尽兴.我喝了很多,我本来挺能喝的.呵呵我们玩了桌球,挺好玩!以前我没有这样玩过.我记得我第一次包宿还是在我大一的时候,张广龙来我着,那时侯我学会了如何上网,那也是第一次接触网络!今天玩通宵是我第二次,我发现我有很多没有大胆的玩过,以前太拘束了!我得慢慢的改变自己,是自己适应很多很有兴趣的生活,学会放松!

人生活在世上要做着自己喜欢的事,并认真地去做,不把这些当作负担,而是有意义的快乐的生活!每一天都过的很轻松,很愉快,这样就会发现生活的乐趣.我还想,人在世上就那么几十年,有一个喜欢而有奋斗目标的工作,一个温馨舒适的家庭,贤惠可亲的妻子,懂事活波的孩子,着就是人间幸事了!

今天下午,我给晓光发短信,叫她去把协议书盖上戳,把协议书寄过来,并问一下我们没有问过的问题.她问过了,院长说以前没有遇见过这种情况,他们也要考虑考虑!

5:00我给晓光打电话,她说她家里对我的态度,说起来她家对我很满意就是没有见过面,害怕我张的太寒碜!呵呵.我心里很高兴!我要好好对她,我要努力(轻松地生活,不然她也挺累),让她生活幸福!现在是2006.4.24.  0:50分了,我写下了今天的日记!

今天很高兴!!!

每次有大的活动,大家都要在一起“聚一聚”,不管是去好乐迪,还是避风塘,或者汤姆熊,大家都要的痛快。还记得心语和花儿在跳舞机上的激情与释放,还记得草草的投篮技艺是如此的高超,还记得狗狗的枪法永远是'S'……还有不能忘了,胖子的歌声永远是让我们惊叫的!! 今天是野猫的生日,所以想到这些也正常,只是因为是上学日,没法一起去了。但回忆一下那时的甜蜜总是一种幸福嘛。。。 但是每次集合的时候都会出现问题!野猫是公认的“路盲”,野猫自己心里也很清楚,每次都提前出门,但还是经常迟到,这点让大家很是无奈。后来,野猫在每次出门前,都会向花儿咨询一下路径,根据已知的路径中,总算能按时到了。 现在提出这样的一个问题:给出 n n 个点的坐标,其中第一个为野猫的出发位置,最后一个为大家的集合位置,并给出哪些位置点是相连的。野猫从出发点到达集合点,总会挑一条最近的路走,如果野猫没找到最近的路,他就会走第二近的路。请帮野猫求一下这条第二最短路径长度。 【输入格式】 第一行是两个整数 n ( 1 ≤ n ≤ 200 ) n(1≤n≤200) 和 m m ,表示一共有 n n 个点和 m m 条路,以下 n n 行每行两个数 x i x i ​ , y i y i ​ , ( − 500 ≤ x i , y i ≤ 500 ) (−500≤x i ​ ,y i ​ ≤500) ,代表第 i i 个点的坐标,再往下的 m m 行每行两个整数 p j p j ​ , q j q j ​ , ( 1 ≤ p j , q j ≤ n ) (1≤p j ​ ,q j ​ ≤n),表示两个点相通。 【输出格式】 只有一行包含一个数,为第二最短路线的距离(保留两位小数),如果存在多条第一短路径,则答案就是第一最短路径的长度;如果不存在第二最短路径,输出 − 1 −1。 【样例输入1】 3 3 0 0 1 1 0 2 1 2 1 3 2 3 【样例输出1】 2.83
最新发布
11-26
这是一个典型的 **求第二短路径(次短路径)** 的图论问题。题目给出了点的坐标,边是通过索引连接的,且所有边权为欧几里得距离。 我们需要从起点(第1个点)到终点(第n个点),找出一条**严格大于最短路径长度的最小路径长度**,即“第二最短路径”。 --- ### ✅ 解题思路 #### 1. 建图 - 每个点有坐标 `(x, y)`,两点之间的距离是欧几里得距离: $$ \text{dist} = \sqrt{(x_1 - x_2)^2 + (y_1 - y_2)^2} $$ - 输入中给出的是哪些点相连(无向边),所以只在这些点之间建边。 #### 2. 求第二短路径 我们可以使用 **扩展 Dijkstra 算法** 来求解: 维护每个节点的两个状态: - `dist[u][0]`:到达 u 的最短距离 - `dist[u][1]`:到达 u 的次短距离 对于每个节点,我们最多保留两个不同的最短距离值(最短和次短)。当通过某条边松弛时,如果得到了一个新的更小的距离(比当前最短或次短小),就更新这两个值。 这种方法的时间复杂度仍然可以接受(O((V + E) log V)),适用于 n ≤ 200。 --- ### ✅ C++ 实现代码(带详细注释) ```cpp #include <iostream> #include <vector> #include <queue> #include <cmath> #include <iomanip> #include <algorithm> using namespace std; const int MAXN = 205; const double INF = 1e15; struct Point { double x, y; }; Point points[MAXN]; vector<pair<int, double>> graph[MAXN]; // 邻接表: to, weight // 用于优先队列:距离、节点 struct State { double dist; int node; bool operator<(const State& other) const { return dist > other.dist; // 最小堆 } }; double dist[MAXN][2]; // dist[i][0]: 最短, dist[i][1]: 次短 void dijkstra_second_shortest(int start, int end, int n) { // 初始化所有距离为无穷大 for (int i = 1; i <= n; ++i) { dist[i][0] = dist[i][1] = INF; } dist[start][0] = 0; priority_queue<State> pq; pq.push({0.0, start}); while (!pq.empty()) { State cur = pq.top(); pq.pop(); double d = cur.dist; int u = cur.node; // 如果当前距离已经大于已知的次短距离,则跳过 if (d > dist[u][1]) continue; for (auto& edge : graph[u]) { int v = edge.first; double w = edge.second; double newDist = d + w; // 尝试更新 v 的最短和次短路径 if (newDist < dist[v][0]) { dist[v][1] = dist[v][0]; dist[v][0] = newDist; pq.push({newDist, v}); } else if (newDist > dist[v][0] && newDist < dist[v][1]) { dist[v][1] = newDist; pq.push({newDist, v}); } } } // 输出结果 if (dist[end][1] == INF) { cout << -1 << endl; } else { // 如果存在多条最短路径,则答案等于最短路径(即第二最短 = 最短) // 如何判断?—— 如果最短 == 次短,则说明有多条最短路径 if (abs(dist[end][0] - dist[end][1]) < 1e-8) { cout << fixed << setprecision(2) << dist[end][0] << endl; } else { cout << fixed << setprecision(2) << dist[end][1] << endl; } } } double euclidean(const Point& a, const Point& b) { double dx = a.x - b.x; double dy = a.y - b.y; return sqrt(dx*dx + dy*dy); } int main() { int n, m; cin >> n >> m; for (int i = 1; i <= n; ++i) { cin >> points[i].x >> points[i].y; } // 清空图 for (int i = 1; i <= n; ++i) { graph[i].clear(); } // 读入 m 条边 for (int i = 0; i < m; ++i) { int p, q; cin >> p >> q; double w = euclidean(points[p], points[q]); graph[p].push_back({q, w}); graph[q].push_back({p, w}); } dijkstra_second_shortest(1, n, n); return 0; } ``` --- ### 🔍 解释说明: 1. **建图过程**: - 使用坐标计算每条边的实际距离。 - 图是无向的,因此双向加边。 2. **Dijkstra 扩展版**: - 每个节点维护两个距离值:最短和次短。 - 使用优先队列进行松弛操作。 - 只有当新距离小于当前次短距离时才加入队列。 3. **输出逻辑**: - 若 `dist[n][1] == INF` → 不存在第二路径 → 输出 `-1` - 若 `dist[n][0] == dist[n][1]`(浮点比较用误差控制)→ 存在多条最短路径 → 输出最短路径长度 - 否则输出次短路径长度(保留两位小数) 4. **样例分析(样例输入1)**: ``` 3 3 0 0 -> A 1 1 -> B 0 2 -> C 边:A-B, A-C, B-C ``` - A(0,0), B(1,1), C(0,2) - AB = √2 ≈ 1.41 - AC = 2.00 - BC = √((1-0)^2 + (1-2)^2) = √2 ≈ 1.41 路径: - 直接 A→C:2.00 - A→B→C:1.41+1.41=2.82 → 四舍五入后输出 2.83 所以最短是 2.00,次短是 2.83 → 输出 `2.83` ✅ 符合样例输出! ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值