There are N cities in the country, and M directional roads from u to v(1≤u,v≤n). Every road has a distance ci c i
Haze is a Magical Girl that lives in City 1, she can choose no more than K roads and make their distances become 0. Now she wants to go to City N, please help her calculate the minimum distance.
Input
The first line has one integer T(1≤T≤5), then following T cases.
For each test case, the first line has three integersN,M and K.
Then the following M lines each line has three integers, describe a road, Ui,Vi,Ci U i , V i , C i
There might be multiple edges between u and v.
It is guaranteed that N≤100000,M≤200000,K≤10,
0≤ Ci C i ≤1e9. There is at least one path between City 1 and City N.
Output
For each test case, print the minimum distance.
样例输入
1
5 6 1
1 2 2
1 3 4
2 4 3
3 4 1
3 5 6
4 5 2
样例输出
3
属于比较裸的分层图dijkstra
主要的思想是 : 优先队列优化的 dij 然后 维护 dis 数组的时候 开一个二维的数组第二维表示第几次边为零的情况,在循环里面加一层判断就行
AC code:
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int maxn = 1e5+50;
const int maxm = 2e5+50;
const int inf = 0x3f3f3f3f;
const int mod = 1e9+7;
struct Node{
int u,v;
ll w;
bool operator<(const Node& a) const {
if ( u == a.u && v == a.v ) return w > a.w;
else if ( u == a.u ) return v < a.v;
else return u < a.u;
}
}edge[maxm];
struct node{
int to,nxt;
ll w;
}star[maxm];
struct res{
ll dis;
int x,level;
res(){}
res(int _x,int _level,ll _dis):x(_x),level(_level),dis(_dis){}
bool operator < (const res &a) const {
return dis > a.dis;
}
};
ll dis[maxn][15],ans;
bool vis[maxn][15];
int n,m,k,head[maxm],cnt;
void init() {
memset(head,0,sizeof(head));
memset(dis,inf,sizeof(dis));
memset(vis,false,sizeof(vis));
cnt = 0; ans = 1e18;
}
inline void add_edge(int u,int v,ll w){
star[++cnt].to = v;
star[cnt].nxt = head[u];
star[cnt].w = w;
head[u] = cnt;
}
void dijkstra(int st) { //分层图dij
priority_queueque;
dis[st][0] = 0;
que.push(res(st,0,0));
while(!que.empty()) {
res e = que.top(); que.pop();
int x = e.x,level = e.level;
if ( vis[x][level] ) continue;
vis[x][level] = true;
for (int i = head[x]; i ; i = star[i].nxt) {
int _to = star[i].to;
if ( dis[x][level] + star[i].w < dis[_to][level] ) {
dis[_to][level] = dis[x][level] + star[i].w;
if(!vis[_to][level])
que.push(res(_to,level,dis[_to][level]));
}
if ( level + 1 <= k && dis[x][level] < dis[_to][level+1] ) {
dis[_to][level+1] = dis[x][level];
if(!vis[_to][level+1])
que.push(res(_to,level+1,dis[_to][level+1]));
}
}
}
}
int main()
{
int t; cin>>t;
while(t--) {
init();
scanf("%d %d %d",&n,&m,&k);
for (int i = 1;i<=m;i++) {
scanf("%d %d %lld",&edge[i].u,&edge[i].v,&edge[i].w);
}
sort(edge+1,edge+m+1);
int peru = -1,perv = -1;
for (int i = 1;i<=m;i++) {
if ( peru != edge[i].u || perv != edge[i].v) {
add_edge(edge[i].u,edge[i].v,edge[i].w);
peru = edge[i].u; perv = edge[i].v;
}
}
dijkstra(1);
for (int i = 0;i<=k;i++) {
ans = min(ans,dis[n][i]);
}
printf("%lld\n",ans);
}
return 0;
}