系兄弟就来砍我 有向图单源最短路
生活随笔
收集整理的這篇文章主要介紹了
系兄弟就来砍我 有向图单源最短路
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
系兄弟就來砍我
時間限制:?1 Sec??內存限制:?128 MB
題目描述
渣渣灰因為一句“大家好,我系渣渣輝,系兄弟就來砍我”引得眾粉絲紛紛拿兩米長的大刀尋找。
現有n個據點,編號(1~n),有m條單向路使據點相連。每個據點僅有一個人。
這n個人中有k個粉絲。其中渣渣灰在s據點處。請問這k個粉絲到渣渣灰的最短距離是多少
輸入
首行輸入nmks。(k<=n<=100m<=500)s為渣渣灰所在位置
接下來m行,每行輸入x,y,z,表示從x到y的距離是z,由于是單向邊,則y到x的距離不一定是z。
接下來k個數字,表示粉絲所在據點。
輸出
對于每一個粉絲,輸出對應的最短距離。
樣例輸入
3 3 2 1 1 2 1 2 3 1 3 1 1 2 3樣例輸出
2 1提示
數據保證k個粉絲均能到達渣渣灰的據點
分析:
Dijkstra算法求單源最短路裸題,因為要求k個粉絲(起點)到?S 終點的最短距離,如果正向建邊,求k次最短路會超時
所以考慮逆向建邊,求S點到所有點的最短距離,儲存在dis數組中
既然要求k個點到s點的最短路,我們可以反過來求s到這k個點的最短路。這樣就變成了單源最短路問題,dijkstra算法和spfa算法都可以做。由于圖為有向圖,我們在存圖時反向存圖即可,原本a[i][j]表示i->j,我們可以將它重新定義為j->i,或者存圖時直接寫成a[j][i]即可。
#include<bits/stdc++.h> using namespace std; const int maxn = 107; const int inf = 0x3f3f3f3f; //需將road及dis初始化為正無窮inf int n,m,k,s; int dis[maxn]; //儲存各個點到源點的最短距離,dis[s]為0 int road[maxn][maxn]; //兩點之間直接距離關系 bool vis[maxn]; //判斷源點到該點的距離是否為最短距離 int fans[maxn]; //粉絲 void dijkstra(int s) {memset(vis, false, sizeof(vis));//標記是否求出最短路徑vis[s] = true;//標記起點到這一點的最小距離已經求出for(int i = 1; i <= n; i++)dis[i] = road[s][i];//初始化起點到每一個點的距離for(int u = 1; u<n; u++){int minD = inf,k = -1;for(int i = 1; i<= n; i++){if(!vis[i]&&dis[i]<minD){k = i;//記錄下標minD = dis[i];//記錄最小值}}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];}//if}//for} } int main() {while(scanf("%d%d%d%d",&n,&m,&k,&s)!=EOF){memset(road,inf,sizeof(road));for(int i=1;i<=m;i++){int a,b,d;scanf("%d%d%d",&a,&b,&d);road[b][a]=min(d,road[b][a]);//逆向建邊//起點是fans[i],終點是S}for(int i=1;i<=k;i++)scanf("%d",&fans[i]);dis[s]=0;dijkstra(s);for(int i=1;i<=k;i++){printf("%d",dis[fans[i]]);if(i==k) printf("\n");else printf(" ");}}return 0; }?
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的系兄弟就来砍我 有向图单源最短路的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 简单的一道题 背包问题
- 下一篇: 躁动的小Z 最短路+路径记录