日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

迷阵突围

發布時間:2023/12/8 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 迷阵突围 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

蒜頭君陷入了坐標系上的一個迷陣,迷陣上有 n 個點,編號從 1 到 n。蒜頭君在編號為 1 的位置,他想到編號為 n 的位置上。蒜頭君當然想盡快到達目的地,但是他覺得最短的路徑可能有風險,所以他會選擇第二短的路徑。現在蒜頭君知道了 n 個點的坐標,以及哪些點之間是相連的,他想知道第二短的路徑長度是多少。
注意,每條路徑上不能重復經過同一個點。

輸入格式
第一行輸入兩個整數 n (1≤n≤200) 和 m,表示一共有 n 個點和 m 條邊。
接下來輸入 n 行,每行輸入兩個整數 xi,yi (?500≤xi,yi≤500),代表第 i 個點的坐標。
接下來輸入 m 行,每行輸入兩個整數pj,qj(1≤pj,qj≤n),表示點 pj和點 qj之間相連。

輸出格式
輸出一行,輸出包含一個數,表示第二短的路徑長度(小數點后面保留兩位),如果第一短路徑有多條,則答案就是第一最短路徑的長度;如果第二最短路徑不存在,則輸出 ?1。

樣例輸入 3 3 1 1 2 2 3 2 1 2 2 3 1 3 樣例輸出 2.41

這道題可“第K短路”那道題是不同的,這道題要求每條路徑上不能重復經過同一個點,但是“第K短路”那道題沒有這個限制。
這道題的正確做法是在點1到點n的路徑上逐個將邊斷開,求最短路。

#include<bits/stdc++.h>#define pii pair<int,int> #define dii pair<double,int> using namespace std; const int N = 205, M = 1e5 + 10; int head[N], ver[M], Next[M], tot = 1; double edge[M], d[N]; int pre[N]; int v[N]; vector<pii > p; int n, m;inline void add(int x, int y, double z) {ver[++tot] = y;edge[tot] = z;Next[tot] = head[x];head[x] = tot; }inline void read() {cin >> n >> m;for (int i = 1; i <= n; i++) {int x, y;scanf("%d%d", &x, &y);p.emplace_back(x, y);}for (int i = 1; i <= m; i++) {int x, y;double z;scanf("%d%d", &x, &y);z = sqrt((p[x - 1].first - p[y - 1].first) * (p[x - 1].first - p[y - 1].first) +(p[x - 1].second - p[y - 1].second) * (p[x - 1].second - p[y - 1].second));add(x, y, z);add(y, x, z);} }void spfa() {for (int i = 2; i <= n; i++)d[i] = 1e9, v[i] = 0;d[1] = 0;v[1] = 1;queue<int> q;q.push(1);while (!q.empty()) {int x = q.front();q.pop();v[x] = 0;for (int i = head[x]; i; i = Next[i]) {int y = ver[i];double z = edge[i];if (d[y] > d[x] + z) {d[y] = d[x] + z;pre[y] = i;if (!v[y]) {v[y] = true;q.push(y);}}}} }double dijkstra() {for (int i = 1; i <= n; i++)d[i] = 1e9, v[i] = 0;priority_queue<dii > q;d[1] = 0;q.push({0, 1});while (!q.empty()) {int x = q.top().second;q.pop();if (v[x])continue;v[x] = 1;for (int i = head[x]; i; i = Next[i]) {int y = ver[i];double z = edge[i];if (d[y] > d[x] + z) {d[y] = d[x] + z;q.push({-d[y], y});}}}return d[n]; }inline void solve() {if (d[n] == 1e9) {printf("-1");return;}int tc = n;double mn = 1e9;while (pre[tc]) {double ke = edge[pre[tc]];edge[pre[tc]] = edge[pre[tc] ^ 1] = 1e9;mn = min(mn, dijkstra());edge[pre[tc]] = edge[pre[tc] ^ 1] = ke;tc = ver[pre[tc] ^ 1];}if (mn >= 1e9)printf("-1");else printf("%.2lf", mn); }int main() {read();spfa();solve();return 0; }

總結

以上是生活随笔為你收集整理的迷阵突围的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。