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\n",ans);
85     }
86     return 0;
87 }
posted @ 2017-08-04 14:55  Kayden_Cheung  阅读(248)  评论(0)    收藏  举报
//目录