• 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
    ");
    45     else cout<<ans<<endl;
    46     return 0;
    47 }
  • 相关阅读:
    Apache 配置多站点访问「为项目分配二级域名」
    php封装的mysqli类完整实例
    PHP实现链式操作的三种方法详解
    php实现简单链式操作mysql数据库类
    PHP PDO_MYSQL 链式操作 非链式操作类
    23个数据库常用查询语句
    微信小程序表单弹窗实例
    ES6 && ECMAScript2015 新特性
    ES6新语法概览
    sql将两个日期之间的日子全列出来
  • 原文地址:https://www.cnblogs.com/demian/p/9196508.html
Copyright © 2020-2023  润新知