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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

codeforces 938D Buy a Ticket 有初值的Dijkstra、有趣的题目

發布時間:2023/12/3 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 codeforces 938D Buy a Ticket 有初值的Dijkstra、有趣的题目 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題意

給出一些城市電影票的價格,以及城市之間交通的路費,詢問每一個城市怎樣才能花最少的錢看到電影(看完電影還要再回來)。

題解

這是一道不太難但是挺有趣的題目。
我們這樣想,每個城市只需要查看票價比他更便宜的城市,來更新本城市的票價就可以了,是不是想到了Dijkstra求最短路的思路。
這樣的話,我們先從票價最便宜的城市開始,從這個城市出發,更新其他所有城市的票價(新票價=原票價+2*路費),然后本城市的票價就求出來了。
再重復上述操作,也就是重新找一個票價最低的城市,然后更新其他城市的票價,這樣就ok啦。

這道題還有一個巨坑,會卡掉一部分人的Dijkstra的代碼,比如我,TLE。
為什么呢?
很多人寫代碼像這樣

while(!pq.empty()){pair<ll,int> p = pq.top();pq.pop();int u = p.second;for(int e = head[u];e != -1;e = es[e].nxt){int v = es[e].v;ll w = es[e].w;if(wa[v] > 2*w+wa[u]){wa[v] = wa[u]+2*w;pq.push(make_pair(wa[v],v));}}}

這樣寫過不了第18組測試數據,因為這樣一組極端數據就卡掉了
n = 200000,m = 199999
200000 1 2
200000 2 4
200000 3 6
200000 4 8

假如優先隊列運行時訪問點的順序是1、2、3、…、200000
那么優先隊列里面會有199999個(dist[200000],200000)點對。
而每有一個這樣的點對,都將會把200000的邊全都遍歷一邊。
時間復雜度就會增加到2000002200000^22000002顯然爆炸,所以要把優先隊列里面多余點對刪掉。
在u點被取出時,增加一句。
if(wa[u] < p.first) continue;
至此,這道題就AC啦。


####代碼

#include <cstdio> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <cstring> using namespace std; typedef long long ll; typedef pair<ll,int> pli; const int maxn = 2e5+10; priority_queue<pli,vector<pli>,greater<pli> > pq; ll wa[maxn]; struct edge{int u,v,nxt;ll w; }es[maxn<<1]; int head[maxn],vis[maxn]; int cnt = 0,n,m; void addedge(int u,int v,ll w){es[cnt].u = u,es[cnt].v = v,es[cnt].nxt = head[u],es[cnt].w = w;head[u] = cnt++; } void solve(){while(!pq.empty()){pair<ll,int> p = pq.top();pq.pop();int u = p.second;if(wa[u] < p.first) continue;for(int e = head[u];e != -1;e = es[e].nxt){int v = es[e].v;ll w = es[e].w;if(wa[v] > 2*w+wa[u]){wa[v] = wa[u]+2*w;pq.push(make_pair(wa[v],v));}}} } int main(){memset(head,-1,sizeof(head));cin>>n>>m;for(int i = 0;i < m;++i){int u,v;ll w;scanf("%d%d%lld",&u,&v,&w);addedge(u,v,w);addedge(v,u,w);}for(int i = 1;i <= n;++i) {ll w;scanf("%lld",&w);wa[i] = w;pq.push(make_pair(w,i));}solve();for(int i = 1;i <= n;++i)printf("%lld ",wa[i]);return 0; }

總結

以上是生活随笔為你收集整理的codeforces 938D Buy a Ticket 有初值的Dijkstra、有趣的题目的全部內容,希望文章能夠幫你解決所遇到的問題。

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