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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

中石油训练赛 - 小说(最短路+二分)

發布時間:2024/4/11 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 中石油训练赛 - 小说(最短路+二分) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目鏈接:點擊查看

題目大意:給出一個無環無向圖,以及k,定義答案是點1到點n的任意一條路徑上,所經過的所有邊的權值中的第k大值,求答案的最小值。(題目是中文題面,沒看懂大意可以直接去看原題目。。)

題目分析:因為是要求權值中的最值,不是求最短路是多少,所以一開始想到的是最小生成樹,然后從大到小減去K個值,就是答案了,可惜的是,最小生成樹的話,不一定會包括最優解,隨便舉個反例,如果我們的k是1,就是需要刪掉一個邊后的最大值,那么有兩條路徑,一條是1,2,9,還有一條是3,3,3,很顯然最小生成樹會選擇第二組邊來生成樹,而不是第一組邊,但是選擇第一組邊的路徑答案是2,第二組的答案是3,故思路明顯錯誤。

然后就要考慮最短路了,畢竟給了一個圖,而且還有權值,題目給了1秒的時間,那么暴力肯定是不行的(雖然暴力我也沒有思路。。),我們可以注意到,每個邊的權值非常小,只有1e6,平常的最短路權值都不會考慮到時間復雜度中去,所以直接給1e9方便,所以我們自然而然可以想到對權值下手,1e6的話如果只是O(n)的話也離超時不遠了,所以考慮一下logn的算法,好吧,是我隊友想出來的,可以二分一下權值,因為答案也是要求輸出一個值,正好就是需要輸出權值,那么我們二分權值后,在迪杰斯特拉中稍微一做修改,就能求出從1到n這條路上需要刪除掉幾條邊才能讓答案滿足我們二分的答案,然后根據這個寫一個check函數,配合上迪杰斯特拉,總時間復雜度就是n*logn*logw了,沒仔細算,不過肯定很小,因為n只有1000,

直接上代碼了,更多的注釋中解釋:

#include<iostream> #include<string> #include<cstring> #include<cstdio> #include<algorithm> #include<climits> #include<cmath> #include<cctype> #include<stack> #include<queue> #include<list> #include<vector> #include<set> #include<map> #include<unordered_map> using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=1e3+100;int limit;int n,m,k;struct Node//Node結構體兩個用途,一個是優先隊列用,一個是鄰接表用 {int to,w;Node(int TO,int W){to=TO;w=W;}bool operator<(const Node& a)const//注意優先隊列的運算符重載是相反的{return w>a.w;} };vector<Node>node[N];int d[N];bool vis[N];void Dijkstra() {for(int i=1;i<=n;i++){d[i]=inf;vis[i]=false;}priority_queue<Node>q;d[1]=0;q.push(Node(1,0));while(!q.empty()){Node temp=q.top();q.pop();if(vis[temp.to])continue;vis[temp.to]=true;int u=temp.to;for(int i=0;i<node[u].size();i++){Node tem=node[u][i];int v=tem.to;int w=tem.w;if(w>limit)//如果該邊的權值大于二分的權值,則令權值為1(表示需要刪除),否則為0w=1;elsew=0;if(d[v]>d[u]+w){d[v]=d[u]+w;q.push(Node(v,d[v]));}}} }bool check(int x) {limit=x;Dijkstra();return d[n]<=k; }int main() {scanf("%d%d%d",&n,&m,&k);while(m--){int u,v,w;scanf("%d%d%d",&u,&v,&w);node[u].push_back(Node(v,w));node[v].push_back(Node(u,w));}limit=1e6+100;Dijkstra();if(d[n]==inf)return 0*printf("-1\n");int l=0;int r=1e6;int ans;while(l<=r){int mid=l+r>>1;if(check(mid)){ans=mid;r=mid-1;}else{l=mid+1;}}cout<<ans<<endl;return 0; }

?

總結

以上是生活随笔為你收集整理的中石油训练赛 - 小说(最短路+二分)的全部內容,希望文章能夠幫你解決所遇到的問題。

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