给定数字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 }