题目链接: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 }