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

题目链接: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 }
原文地址:https://www.cnblogs.com/doggod/p/8496058.html