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

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

一道有趣的最短路 NEERC2017 Journey from Petersburg to Moscow

發(fā)布時(shí)間:2023/12/3 编程问答 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 一道有趣的最短路 NEERC2017 Journey from Petersburg to Moscow 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

題目鏈接

http://codeforces.com/gym/101630/attachments/download/6401/20172018-acmicpc-northeastern-european-regional-contest-neerc-17-en.pdf

題意

11nn的最短路,最短路上只計(jì)算前kk大的邊。

題解

這道題的操作很騷,算法如下:
遍歷每條邊xx,并把圖中所有的邊的權(quán)值都減去該邊的權(quán)值xx,如果變成負(fù)數(shù),那么就置00,并將跑出來(lái)的值dis[n]+k?xdis[n]+k?x就是這次的答案,對(duì)所有的答案取最小值,并且與原始圖的dis[n]dis[n]取最小值,得到的結(jié)果就是最終答案。

正確性證明:
1. 假設(shè)最終的最短路中有大于等于kk條邊,并設(shè)第kk大的邊長(zhǎng)度為xx
那么該路徑上所有的邊減去xx,之后跑最短路得到dis[n]dis[n],那么dis[n]+k?xdis[n]+k?x就是該路徑的“長(zhǎng)度”,就是最終答案,并且這個(gè)數(shù)一定會(huì)出現(xiàn)在比較中。
而對(duì)于其他的路徑,如果減去的xx不是該路徑的第kk大的邊的時(shí)候,該路徑的值dis[n]+k?xdis[n]+k?x一定不會(huì)比該路徑的“長(zhǎng)度”小,出現(xiàn)在比較中不會(huì)對(duì)最終答案造成影響。
2. 假設(shè)最短路中有小于k條邊,那么原圖中跑最短路的dis[n]dis[n]一定是最小的。

注意,此題用spfa超時(shí),用dijkstra也有稍微優(yōu)化一下才行。

代碼

#include <cstdio> #include <iostream> #include <vector> #include <cstring> #include <queue> using namespace std; const int maxn = 3007; vector<int> G[maxn]; typedef long long ll; typedef pair<ll,int> pii; const ll inf = 1e18; int U[maxn],V[maxn];long long W[maxn]; int n,m,k; int vis[maxn];ll dis[maxn]; #define pr(x) cout<<#x<<":"<<x<<endl /* ll spfa(ll x){memset(vis,0,sizeof(vis));for(int i = 1;i <= n;++i) dis[i] = inf;queue<int> Q;vis[1] = 1;Q.push(1);dis[1] = 0;while(!Q.empty()){int u = Q.front();Q.pop();vis[u] = 0;for(auto e : G[u]){int v = U[e]^V[e]^u;ll w = W[e] - x;w = max(0ll,w);if(dis[v] > dis[u] + w){if(!vis[v]) Q.push(v);dis[v] = dis[u] + w;vis[v] = 1;}}}return dis[n]; } */ ll dij(ll x){priority_queue<pii,vector<pii>,greater<pii> > Q;for(int i = 1;i <= n;++i) dis[i] = inf;dis[1] = 0;Q.push({0,1});while(!Q.empty()){pii p = Q.top();Q.pop();int u = p.second;if(p.first > dis[u]) continue;for(int e : G[u]){int v = u ^ U[e] ^ V[e];ll w = W[e] - x;w = max(0ll,w);if(dis[v] > dis[u] + w){dis[v] = dis[u] + w;Q.push({dis[v],v});}}}return dis[n]; } int main(){cin>>n>>m>>k;for(int i = 0;i < m;++i){int u,v;long long w;scanf("%d %d %lld",&u,&v,&w);U[i] = u,V[i] = v,W[i] = w;G[u].push_back(i);G[v].push_back(i);}ll ans = dij(0);for(int i = 0;i < m;++i){ll res = dij(W[i])+k*W[i];ans = min(ans,res);}printf("%lld\n",ans);return 0; }

總結(jié)

以上是生活随笔為你收集整理的一道有趣的最短路 NEERC2017 Journey from Petersburg to Moscow的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。