题目链接

题意

有N个城市M条路径,可以使K条路径长度变为0,求1到N最短路

解题思路

求最短路很好求,但是题目多了一个限制条件,可以使K条路径长度变为0,这就有点麻烦了,后来想到,这也有点像01背包选与不选的感觉,求最短路的时候加个状态就可以求解了

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5+500;
struct Edge
{
int to,val;
};
vector<Edge> G[maxn];
typedef pair<int,int> pii;
typedef pair<ll,pii> PII;
ll dis[15][maxn];

int dijkstra(int N,int K)
{
priority_queue<PII,vector<PII>,greater<PII> > Q;
Q.push(PII(0,pii(1,K)));
memset(dis,0x3f,sizeof(dis));
dis[K][1] = 0;
while(!Q.empty()){
PII t = Q.top();
Q.pop();
int d = t.first;
int u = t.second.first;
int k = t.second.second;

for(int i=0;i<G[u].size();i++){
Edge e = G[u][i];
if( dis[k][e.to] > dis[k][u] + e.val){
dis[k][e.to] = dis[k][u] + e.val;
Q.push(PII(dis[k][e.to],pii(e.to,k)));
}
if(k > 0 && dis[k][u] < dis[k-1][e.to]){
dis[k-1][e.to] = dis[k][u];
Q.push(PII(dis[k-1][e.to],pii(e.to,k-1)));
}
}
}
return dis[0][N];
}

int main(int argc, char const *argv[])
{
int T = 0;
scanf("%d",&T);
int N,M,K;
while(T--){
scanf("%d%d%d",&N,&M,&K);
for(int i=0;i<=N;i++){
G[i].clear();
}
int a,b,c;
for(int i=0;i<M;i++){
scanf("%d%d%d",&a,&b,&c);
Edge t = (Edge){b,c};
G[a].push_back(t);
}
int ans = dijkstra(N,K);
printf("%d\n",ans);
}

return 0;
}