中石油训练赛 - 小说(最短路+二分)
題目鏈接:點擊查看
題目大意:給出一個無環無向圖,以及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; }?
總結
以上是生活随笔為你收集整理的中石油训练赛 - 小说(最短路+二分)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 中石油训练赛 - 小A进学校(唯一分解定
- 下一篇: HDU - 1728 逃离迷宫(bfs)