PTA 旅遊規劃(25 分)
阿新 • • 發佈:2017-12-25
title 收費 () 輸出 格式 分開 i++ namespace push
7-10 旅遊規劃(25 分)
有了一張自駕旅遊路線圖,你會知道城市間的高速公路長度、以及該公路要收取的過路費。現在需要你寫一個程序,幫助前來咨詢的遊客找一條出發地和目的地之間的最短路徑。如果有若幹條路徑都是最短的,那麽需要輸出最便宜的一條路徑。
輸入格式:
輸入說明:輸入數據的第1行給出4個正整數N、M、S、D,其中N(2≤N≤500)是城市的個數,順便假設城市的編號為0~(N?1);M是高速公路的條數;S是出發地的城市編號;D是目的地的城市編號。隨後的M行中,每行給出一條高速公路的信息,分別是:城市1、城市2、高速公路長度、收費額,中間用空格分開,數字均為整數且不超過500。輸入保證解的存在。
輸出格式:
在一行裏輸出路徑的長度和收費總額,數字間以空格分隔,輸出結尾不能有多余空格。
輸入樣例:
4 5 0 3
0 1 1 20
1 3 2 30
0 3 4 10
0 2 2 20
2 3 1 20
輸出樣例:
3 40
#include<bits/stdc++.h> using namespace std; #define maxn 0x7fffffff int mat[505][505],vis[505],pay[505][505]; /* mat 是圖的鄰接矩陣表示,vis是標記數組 , pay 是花費的鄰接矩陣表示 */ int dis[505],cost[505],n,m,path[505]; //最短路 + 路徑輸出 //n 是點的個數 標記為 0 ~ n-1 , //dis 最短路記錄數組,cost 最小花費記錄數組,path 路徑記錄數組 void dijkstra(int s) //修改後的最短路算法,+path 記錄 和 花費計算 { int i,j; memset(vis,0,sizeof(vis));//清空標記數組 for(i=0;i<n;i++) { /* 用mat臨接矩陣的值初始化dis 的值 用pay臨接矩陣的值初始化cost 的值 */ dis[i]=mat[s][i]; cost[i]=pay[s][i]; if(dis[i]!=maxn) //無窮大代表此路不通 path[i] =-1,否則就在路徑加入這個點 path[i]=s; else path[i]=-1; } vis[s]=1;//起始點標記 dis[s]=0;//自己到自己的花費cost = 0 cost[s]=0; for(i=1;i<n;i++) { int k=s,u=maxn; /* 找出到s距離最短&沒標記的點,作為中轉點更新dis值 */ for(j=0;j<n;j++) { if(!vis[j]&&dis[j]<u) { u=dis[j]; k=j; } } vis[k]=1;//標記這個點 for(j=0;j<n;j++) { if(!vis[j]&&mat[k][j]!=maxn) { /* 用這個點更新dis值,cost 和 dis同步更新,參數值相同 如果把k作為中轉點成功縮減了dis值,就讓k點加入path路徑裏 */ if(dis[j]>dis[k]+mat[k][j]) { dis[j]=dis[k]+mat[k][j]; cost[j]=cost[k]+pay[k][j]; path[j]=k; } /* 最短路徑dis相同的話,選擇花費最少的,最小cost */ else if(dis[j]==dis[k]+mat[k][j]) { /* 如果這個花費更加優,那麽把這個點加入,更新最優秀的路徑 最後path裏面記錄的是最優路徑 */ if(cost[j]>cost[k]+pay[k][j]) { cost[j]=cost[k]+pay[k][j]; path[j]=k; } } } } } } void print(int s,int t) { stack<int>q; /* 從path裏溯源t = path[t],返回上一個和t聯通的路徑,由後往前,把s~t路徑放入隊列裏面,然後輸出 */ while(t!=s) { q.push(t); t=path[t]; } q.push(t); while(!q.empty()) { cout<<q.top()<<" "; q.pop(); } } int main() { int s,t,a,b,d,w,i,j; cin>>n>>m>>s>>t; for(i=0;i<n;i++) for(j=0;j<n;j++) mat[i][j]=pay[i][j]=maxn; /* 初始化數組,讓距離鄰接矩陣數組值 = 無窮大,花費鄰接矩陣的值 = 無窮大 這個計算方式對無向圖和有向圖同樣適用,只需要部分修改 */ for(i=0;i<m;i++) { cin>>a>>b>>d>>w; if(mat[a][b]>d) { mat[a][b]=mat[b][a]=d; pay[a][b]=pay[b][a]=w; } else if(mat[a][b]==d) { if(pay[a][b]>w) pay[a][b]=pay[b][a]=w; } // 輸入進行處理,最短路 } dijkstra(s); // 尋找從 s 開始 單源最短路 // print(s,t);// 輸出路徑, S 到 T 的路徑 cout<<dis[t]<<" "<<cost[t]<<endl; // dist 指的是 距離 dis[t] 指的是花費 return 0; }
PTA 旅遊規劃(25 分)