暢通工程續(HDU 1874 迪傑斯特拉+優先佇列)
阿新 • • 發佈:2018-12-17
暢通工程續
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 71911 Accepted Submission(s): 27860
Problem Description
某省自從實行了很多年的暢通工程計劃後,終於修建了很多路。不過路多了也不好,每次要從一個城鎮到另一個城鎮時,都有許多種道路方案可以選擇,而某些方案要比另一些方案行走的距離要短很多。這讓行人很困擾。 現在,已知起點和終點,請你計算出要從起點到終點,最短需要行走多少距離。
Input
本題目包含多組資料,請處理到檔案結束。 每組資料第一行包含兩個正整數N和M(0<N<200,0<M<1000),分別代表現有城鎮的數目和已修建的道路的數目。城鎮分別以0~N-1編號。 接下來是M行道路資訊。每一行有三個整數A,B,X(0<=A,B<N,A!=B,0<X<10000),表示城鎮A和城鎮B之間有一條長度為X的雙向道路。 再接下一行有兩個整數S,T(0<=S,T<N),分別代表起點和終點。
Output
對於每組資料,請在一行裡輸出最短需要行走的距離。如果不存在從S到T的路線,就輸出-1.
Sample Input
3 3
0 1 1
0 2 3
1 2 1
0 2
3 1
0 1 1
1 2
Sample Output
2 -1
Author
linle
Source
原始碼:
#include<iostream> #include<cstdio> #include<cstring> #include<vector> #include<queue> using namespace std; struct CNode{ int k; int w; }; bool operator < (const CNode &d1,const CNode &d2){ return d1.w>d2.w; } priority_queue <CNode> pq; int vis[10010]={0}; int flag; vector <vector <CNode> > v;//表示整個圖 int main(void){ int n,m;//代表已有城鎮數目和已經修建的道路的數目 int a,b,x; int i,j; CNode p; while(~scanf("%d %d",&n,&m)){ v.clear(); v.resize(n+1); while(!pq.empty()){ pq.pop(); } memset(vis,0,sizeof(vis)); for(i=0;i<m;i++){ scanf("%d %d %d",&a,&b,&x); p.k=b;//設定終點 p.w=x;//設定花費 v[a].push_back(p);//在圖的尾部不斷加入p p.k=a; v[b].push_back(p); } int s,e; scanf("%d %d",&s,&e); p.k=s; p.w=0; pq.push(p); while(!pq.empty()){ p=pq.top(); pq.pop(); flag=0; if(vis[p.k]) continue; vis[p.k]=1; if(p.k==e){ flag=1; printf("%d\n",p.w); break; } for(i=0,j=v[p.k].size();i<j;i++){ //迪傑斯特拉演算法核心 CNode q; q.k=v[p.k][i].k; q.w=p.w+v[p.k][i].w; pq.push(q); } } if(flag==0) printf("-1\n"); } }
思考:
這道題屬於迪傑斯特拉演算法的簡單運用,在暑假集訓的時候看過poj3159那道題,那道題是求1到N的最短路。那麼在這裡是做一下變形,新增兩個人為的起點和終點。