1. 程式人生 > >Codeforces 938 D. Buy a Ticket (dijkstra 求多元最短路)

Codeforces 938 D. Buy a Ticket (dijkstra 求多元最短路)

code 簡單 max back tin 不可 bsp for i++

題目鏈接:Buy a Ticket

題意:

  給出n個點m條邊,每個點每條邊都有各自的權值,對於每個點i,求一個任意j,使得2×d[i][j] + a[j]最小。

題解:

  這題其實就是要我們求任意兩點的最短路,但是從點的個數上就知道這題不可以用floyd算法,其實多元最短路可以用dijkstra算。@。@!把所有的點的權值和點放到結構體裏面,放入優先隊列,其實這樣就能保證每次拓展到的點就是這個點的最短路(因為是優先隊列,保證拓展到的點這時候的值是最小的),其實就是這個點想通就很簡單。

 1 #include<bits/stdc++.h>
 2 using namespace std;
3 typedef pair<long long,long long> P; 4 const int MAX_N = 2e5+9; 5 vector<P> vec[MAX_N]; 6 long long vis[MAX_N],val[MAX_N]; 7 priority_queue< P , vector<P> , greater<P> > que; 8 int N,M,x; 9 void init() 10 { 11 for(int i=0;i<MAX_N;i++) vec[i].clear(); 12 while
(!que.empty()) que.pop(); 13 memset(vis,0,sizeof(vis)); 14 memset(val,0,sizeof(val)); 15 } 16 int main() 17 { 18 cin>>N>>M; 19 init(); 20 for(int i=0;i<M;i++) 21 { 22 long long a,b,c; 23 scanf("%lld%lld%lld",&a,&b,&c); 24 vec[a].push_back(P(b,2
*c)); 25 vec[b].push_back(P(a,2*c)); 26 } 27 for(int i=1;i<=N;i++) 28 { 29 long long t; 30 scanf("%lld",&t); 31 que.push(P(t,i)); 32 } 33 34 while(!que.empty()) 35 { 36 P p = que.top();que.pop(); 37 if(vis[p.second]) continue; 38 vis[p.second] = 1; 39 val[p.second] = p.first; 40 for(int i=0;i<vec[p.second].size();i++) 41 { 42 que.push(P(p.first+vec[p.second][i].second , vec[p.second][i].first)); 43 } 44 } 45 46 for(int i=1;i<=N;i++) printf("%lld ",val[i]); 47 cout<<endl; 48 return 0; 49 }

Codeforces 938 D. Buy a Ticket (dijkstra 求多元最短路)