CDOJ 1964 命运石之门【最短路径Dijkstra】

给定数字n,m(1<=n,m<=500000)

将n变为n*2花费2,将n变为n-3花费3,要求过程中所有数字都在[1,500000]区间内。

求将n变为m的最少花费

思路:建图

将每个数字视为图中的点,数字之间的转换视为图中的边,有向图。

500000个点,(i,i*2)权值为2,(i,i-3)权值为3

转换为求n至m的最短路径

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int INF = 0x3f3f3f3f;
 4 int n,m;
 5 vector<pair<int,int>> edge[500001];
 6 int dis[500001];
 7 typedef pair<int,int> P;//first 最短距离,second顶点编号
 8 
 9 void dijkstra(int s)
10 {
11     memset(dis,INF, sizeof(dis));
12     priority_queue<P,vector<P>,greater<P>> que; //最小堆
13     que.push(P(0,s));
14     dis[s]=0;
15     while(que.size())
16     {
17         P p=que.top();que.pop();
18         int v = p.second;
19         //vis[v]=1;
20         if(dis[v]<p.first)continue;
21         for(int i=0;i<edge[v].size();i++)
22         {
23             int to = edge[v][i].second;
24             int cost = edge[v][i].first;
25             //if(!vis[to]&&dis[to]>dis[v]+cost)
26             if(dis[to]>dis[v]+cost)
27             {
28                 dis[to]=dis[v]+cost;
29                 que.push(P(dis[to],to));
30             }
31         }
32     }
33     if(dis[m]==INF)
34         cout<<-1<<endl;
35     else
36         cout<<dis[m];
37 }
38 
39 int main() {
40     cin >> n >> m;
41     for (int i = 1; i <= 500000; i++)
42     {
43         if(2*i<500000)
44             edge[i].push_back(make_pair(2,2*i));
45         if(i-3>0)
46             edge[i].push_back(make_pair(3,i-3));
47     }
48     dijkstra(n);
49     return 0;
50 }

猜你喜欢

转载自www.cnblogs.com/demian/p/9196508.html
今日推荐