牛客網 短最優升級路徑 【Dijkstra演算法】+【路徑記錄】
阿新 • • 發佈:2018-12-21
短最優升級路徑
題目描述:遊戲網站提供若干升級補丁,每個補丁大小不一,玩家要升級到最新版,如何選擇下載哪些補丁下載量最小。
輸入:
第一行輸入
第一個數為使用者版本 第二個數為最新版本,空格分開
接著輸入N行補丁資料
第一個數補丁開始版本 第二個數為補丁結束版本 第三個數為補丁大小,空格分開
輸出:
對於每個測試例項,輸出一個升級路徑以及最後實際升級的大小
樣例輸入:
1000 1050
1000 1020 50
1000 1030 70
1020 1030 15
1020 1040 30
1030 1050 40
1040 1050 20
樣例輸出:
1000->1020->1040->1050(100)
迪傑斯特拉最短路徑演算法 建立鄰接矩陣,標識版本間的來去路線,求最初版本到最末版本之間的最短路徑。
在dijkstra演算法模板的基礎上加上一個pre陣列,用於記錄該節點的上一個節點,即該點是經過哪一點才到達該點的。pre陣列具體在邊鬆弛的過程中進行重新賦值,鬆弛成功就將pre值記錄k點,及該點是由起點經過k點後所得到的。最後把pre陣列中的值遞迴輸出一遍即可。
#include <cstdio> #include <cstring> #include <queue> #include <algorithm> #include<bits/stdc++.h> using namespace std; typedef long long LL; const int maxn=10000; #define INF 0x3f3f3f3f #define inf 0x3f3f3f3f map<int,int> mp,rmp; int road[maxn][maxn]; int dis[maxn]; bool vis[maxn]; int pre[maxn]; int n; void dijkstra(int s,int e) {//s為起點,e為終點 memset(vis, false, sizeof(vis));//標記是否求出最短路徑 vis[s] = true;//標記起點到這一點的最小距離已經求出 for(int i = 1; i < n; i++){ dis[i] = road[s][i];//初始化起點到每一個點的距離 pre[i]=s;//初始化路徑,每個點的上一個點為起點 } for(int u = 1; u < n-1; u++) { int minD =inf ,k = -1; for(int i = 1; i< n; i++) { //尋找沒有訪問過的最短路 if(!vis[i]&&dis[i]<minD) { k = i;//記錄下標 minD = dis[i];//記錄最小值 } } if(k==e) break; vis[k] = true;//標記已經訪問過 //鬆弛操作 for(int i = 1; i< n; i++) { if(!vis[i]&&dis[k]+road[k][i]<dis[i]) { dis[i]=dis[k]+road[k][i]; pre[i]=k; }//if }//for } } void print(int cur){ if(cur==1){ printf("%d",rmp[cur]); return ; } print(pre[cur]); printf("->%d",rmp[cur]); } int main(){ int start,end; n=1; scanf("%d%d",&start,&end); rmp.clear(); mp.clear(); mp[start]=n; rmp[n]=start; n++; mp[end]=n; rmp[n]=end; n++; int N=(end-start)/10; memset(road,INF,sizeof road); for(int i=0;i<=N;i++){ int u,v,w; scanf("%d%d%d",&u,&v,&w); if(!mp[u]) { mp[u]=n; rmp[n]=u; n++; } if(!mp[v]) { mp[v]=n; rmp[n]=v; n++; } road[mp[u]][mp[v]]=road[mp[v]][mp[u]]=min(road[mp[v]][mp[u]],w); } for(int i=1;i<n;i++){ for(int j=1;j<n;j++) printf("%d ",road[i][j]==INF?-1:road[i][j]); printf("\n"); } dijkstra(mp[start],mp[end]); if(dis[mp[end]]==INF) printf("-1"); else { print(mp[end]); printf("(%d)\n",dis[mp[end]]); } return 0; }