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 }