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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

path hdu6705

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

題意:

一個有向加權圖,問所有路徑匯中第k小的路徑長度是多少?
注意一個邊可以反復走多次

題解

做法參考
我們可以利用優先隊列來做
利用優先隊列實現每次所取為最短邊
我們假設一條路是從u—>v,路徑和為sum,u->v是u的所以出邊中邊權第cur小的邊,那么我們接下來有兩種方案可以走:
第一種:就是接著從v走下去,從v繼續走到v->w,(w為距離v最近的點,w!=u),cur為0,因為w是v第(cur+1)小的選擇,也就是g[v][0]=w
此時sum+g[v][0]
第二種:
我認為這一步算是返回的步驟
就是繼續從u出發,走u下一個邊權較大于v的點,因為v是第cur小的選項,所以此等方案為cur+1
sum-g[u][cur].w+g[u][cur+1].w
我們的sum是記錄了u到v的邊權,所以先去掉,再加上新邊權

代碼中的cur是用來距離v是u的第幾小的選擇,
我們全程不斷計算新的路徑情況,并將路徑長度存到優先隊列q中,不斷排序

代碼

#include<bits/stdc++.h> #define LL long long using namespace std; const int INF=0x3f3f3f3f; const int maxn=5e5+50; int n,m,q; LL ans[maxn]; struct edge {int to;LL w; }; vector<edge> g[maxn]; bool cmp(const edge &x,const edge &y) {return x.w<y.w; } struct node {int u,v;int cur;LL sum;friend bool operator < (const node &x,const node &y){return x.sum>y.sum;} }; void init() {for(int i=1;i<=n;i++)g[i].clear(); } void solve() {for(int i=1;i<=n;i++)sort(g[i].begin(),g[i].end(),cmp);priority_queue<node> q;for(int i=1;i<=n;i++){if(!g[i].empty())q.push(node{i,g[i][0].to,0,g[i][0].w});}for(int i=1;i<=50000;i++){int u=q.top().u,v=q.top().v,cur=q.top().cur;LL sum=q.top().sum;q.pop();ans[i]=sum;if(!g[v].empty())q.push(node{v,g[v][0].to,0,sum+g[v][0].w});if(cur+1<g[u].size())q.push(node{u,g[u][cur+1].to,cur+1,sum-g[u][cur].w+g[u][cur+1].w});} } int main() {int T;scanf("%d",&T);while(T--){scanf("%d %d %d",&n,&m,&q);init();for(int i=1;i<=m;i++){int u,v,w;scanf("%d %d %d",&u,&v,&w);g[u].push_back(edge{v,w});}solve();while(q--){int k;scanf("%d",&k);printf("%lld\n",ans[k]);}}return 0; }

總結

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

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