zoukankan      html  css  js  c++  java
  • HDU 6071 Lazy Running(很牛逼的最短路)

    http://acm.hdu.edu.cn/showproblem.php?pid=6071

    题意:

    1、2、3、4四个点依次形成一个环,现在有个人从2结点出发,每次可以往它相邻的两个结点跑,求最后回到2结点并且不少于K的最短距离。

    思路:

    官方题解:

    最后的答案可以表示为:$ans=p*(2w)+m$,这样一来,m的取值范围就是$(0<=m<2w)$,而因为m的不同,p值也会有所不同。所以我们用 d [ i ] [ m ]表示从起点出发,最后到达 i 点,距离对2w取模为m时的最小距离,这个计算一下最短路即可。

    最后只需要枚举m,如果此时d [ 2 ] [ m ]不足K的话,那么就再加上2w补足即可,在所有的m中取最小值。

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<cstdio>
     5 #include<sstream>
     6 #include<vector>
     7 #include<stack>
     8 #include<queue>
     9 #include<cmath>
    10 #include<map>
    11 #include<set>
    12 using namespace std;
    13 typedef long long ll;
    14 typedef pair<int,ll> pll;
    15 const ll INF = 2000000000000000000000;
    16 const int maxn=1e6+5;
    17 
    18 ll k;
    19 ll m;
    20 ll d[5];
    21 ll dis[5][maxn];
    22 vector<pll> G[5];
    23 
    24 struct HeapNode
    25 {
    26     int u; ll w;
    27     HeapNode(int x, ll y) :u(x), w(y){}
    28     bool operator <(const HeapNode& rhs) const{
    29         return w>rhs.w;
    30     }
    31 };
    32 
    33 void dijkstra()
    34 {
    35     priority_queue<HeapNode> Q;
    36     for(int i=0;i<4;i++)
    37     for(int j=0;j<=m;j++)  dis[i][j]=INF;
    38 
    39     Q.push(HeapNode(1,0));
    40     while(!Q.empty())
    41     {
    42         HeapNode p=Q.top(); Q.pop();
    43         int u=p.u;
    44         ll w=p.w;
    45 
    46         for(int i=0;i<G[u].size();i++)
    47         {
    48             int v=G[u][i].first;
    49             ll new_w=G[u][i].second+w;
    50             if(dis[v][new_w%m]>new_w)
    51             {
    52                 dis[v][new_w%m]=new_w;
    53                 Q.push(HeapNode(v,new_w));
    54             }
    55         }
    56     }
    57 }
    58 
    59 int main()
    60 {
    61     //freopen("in.txt","r",stdin);
    62     int T;
    63     scanf("%d",&T);
    64     while(T--)
    65     {
    66         scanf("%lld",&k);
    67         for(int i=0;i<4;i++)  G[i].clear();
    68         for(int i=0;i<4;i++)
    69         {
    70             scanf("%lld",&d[i]);
    71             G[i].push_back(make_pair((i+1)%4,d[i]));
    72             G[(i+1)%4].push_back(make_pair(i,d[i]));
    73         }
    74         m=2*min(d[0],d[1]);
    75         dijkstra();
    76 
    77         ll ans=INF;
    78         for(int i=0;i<m;i++)
    79         {
    80             ll tmp=k-dis[1][i];
    81             if (tmp<=0) ans=min(ans,dis[1][i]);
    82             else ans=min(ans,dis[1][i]+(ll)ceil((long double)tmp/m)*m);
    83         }
    84         printf("%lld
    ",ans);
    85     }
    86     return 0;
    87 }
  • 相关阅读:
    超有爱的并查集
    写给想当程序员的朋友
    POJ 1961 字符串 KMP (i-next[i])
    POJ 2406 KMP算法next数组理解
    POJ 2387 Bellman双重边
    POJ 1917 字符串替换
    POJ 1062 坑爹的聘礼(枚举等级差选择性找边)
    Linux下libxml2的使用
    浙大pat 1003
    判定一棵二叉树是否是二叉搜索树
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/7285141.html
Copyright © 2011-2022 走看看