P4568 [JLOI2011]飞行路线

原题链接

考察:最短路

思路:

        拆点.只有一个状态不足以求出最小花费,需要再加上当前点用了几次免费机会.

坑点:

       存在起点与终点经过路线<k的情况,这时候用不到k次机会,所以直接返回0的贪心是错的....

 1 #include <iostream>
 2 #include <cstring>
 3 #include <queue>
 4 using namespace std;
 5 const int N = 10010,M = 50010,KS = 12;
 6 int n,m,K,h[N],s,e,dist[N][KS],idx;
 7 bool st[N][KS];
 8 struct Road{
 9     int to,ne,w;
10 }road[M<<1];
11 struct Node{
12     int idx,k,cost;
13     bool operator>(const Node& n)const{
14          return this->cost>n.cost;
15     }
16 };
17 void add(int a,int b,int w)
18 {
19     road[idx].to = b,road[idx].w = w,road[idx].ne = h[a],h[a] = idx++;
20 }
21 int dijkstra(int s)
22 {
23     priority_queue<Node,vector<Node>,greater<Node> > q;
24     memset(dist,0x3f,sizeof dist);
25     dist[s][K] = 0;
26     q.push({s,K,0});
27     while(q.size())
28     {
29         Node it = q.top();
30         q.pop();
31         int cost = it.cost,k = it.k,u = it.idx;
32         if(st[u][k]) continue;
33         st[u][k] = 1;
34         for(int i=h[u];~i;i=road[i].ne)
35         {
36             int v = road[i].to;
37             if(k&&dist[v][k-1]>dist[u][k])
38             {
39                 dist[v][k-1] = dist[u][k];
40                 q.push({v,k-1,dist[v][k-1]});
41             }
42             if(dist[v][k]>dist[u][k]+road[i].w)
43             {
44                 dist[v][k] = dist[u][k]+road[i].w;
45                 q.push({v,k,dist[v][k]});
46             }
47         }
48     }
49     int res = 0x3f3f3f3f;
50     for(int i=1;i<=n;i++) res = min(res,dist[e][i]);
51     return res;
52 }
53 int main()
54 {
55     scanf("%d%d%d%d%d",&n,&m,&K,&s,&e);
56     memset(h,-1,sizeof h);
57     while(m--)
58     {
59         int a,b,c; scanf("%d%d%d",&a,&b,&c);
60         add(a,b,c); add(b,a,c);
61     }
62     printf("%d\n",dijkstra(s));
63     return 0;
64 }

 

posted @ 2021-05-01 16:48  acmloser  阅读(55)  评论(0编辑  收藏  举报