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

给定数字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 long long INF = 0x3f3f3f3f3f3f3f3f;
 4 int n,m;
 5 vector<pair<long long,int>> edge[500001];
 6 long long dis[500001];
 7 typedef pair<long long,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             long long 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 }

 思路2:暴力BFS

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int INF = 0x3f3f3f3f;
 4 typedef long long LL;
 5 int n,m;
 6 struct node
 7 {
 8     int x;
 9     LL cost;
10 };
11 int vis[500002];
12 
13 int main() {
14     cin >> n >> m;
15     node cur,now;
16     cur.x=n,cur.cost=0;
17     queue<node> q;
18     q.push(cur);
19     LL ans=1e18;
20     vis[cur.x]=1;
21     while(q.size())
22     {
23         now=q.front();q.pop();
24         if(now.x==m)
25         {
26             ans=min(ans,now.cost);
27             continue;//剪枝
28         }
29         cur.x=now.x*2;
30         cur.cost=now.cost+2;
31         if(cur.x<=500000&&!vis[cur.x])
32         {
33             vis[cur.x]=1;
34             q.push(cur);
35         }
36         cur.x=now.x-3;
37         cur.cost=now.cost+3;
38         if(cur.x>0&&!vis[cur.x])
39         {
40             vis[cur.x]=1;
41             q.push(cur);
42         }
43     }
44     if(ans==1e18) printf("-1\n");
45     else cout<<ans<<endl;
46     return 0;
47 }

 

posted @ 2018-06-18 22:12  demianzhang  阅读(342)  评论(0编辑  收藏  举报