There are N cities in the country, and M directional roads from uto v(1≤u,v≤n). Every road has a distance ci. 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 integers N,M and K.
Then the following MMM lines each line has three integers, describe a road, Ui,Vi,Ci There might be multiple edges between u and v.
It is guaranteed that N≤100000,M≤200000,K≤10,0≤Ci≤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
题意:
给你n个城市,m条路,每条路都要花费一定的时间,现在有个人想从城市1走到城市n,但是他可以选最多k条路把它的时间变成0,问他走到城市n的最少时间。
做法:
很明显因为存在k条可变的边,普通的最短路肯定做不了,需要用到一定的dp,dp[i][j]代表走到点i,用掉j次机会所用的最少时间。要配合dijkstra一起更新,同时设定一个vis来剪枝,就可以过了。
#include<cstring>
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
using namespace std;
typedef long long ll;
const int mod=(int)1e9+7;
const int maxn=100005;
const ll inf=1e17;
int n,m,head[maxn],now,k;
bool vis[maxn][11];
ll dp[maxn][11];
struct node{
int to,next;
ll w;
}e[2*maxn];
void add(int u,int v,ll w){
e[now].to=v; e[now].w=w;
e[now].next=head[u],head[u]=now++;
}
struct Node{
ll dis;
int id,num;
Node(int num,int dis,int id):num(num),dis(dis),id(id){}
bool operator < (const Node &a)const{
if(dis!=a.dis) return dis>a.dis;
return num>a.num;
}
};
void dij(int st){
priority_queue<Node> q;
q.push(Node(0,0,st));
dp[st][0]=0;
while(!q.empty()){
Node u=q.top(); q.pop();
if(vis[u.id][u.num]) continue;
vis[u.id][u.num]=1;
for(int i=head[u.id];~i;i=e[i].next){
int v=e[i].to;
if(dp[v][u.num]-e[i].w>dp[u.id][u.num]){
dp[v][u.num]=dp[u.id][u.num]+e[i].w;
q.push(Node(u.num,dp[v][u.num],v));
}
if(u.num<k&&dp[v][u.num+1]>dp[u.id][u.num]){
dp[v][u.num+1]=dp[u.id][u.num];
q.push(Node(u.num+1,dp[v][u.num+1],v));
}
}
}
}
void init(){
memset(vis,0,sizeof(vis));
memset(head,-1,sizeof(head));
memset(dp,125,sizeof(dp));
now=0;
}
int main(){
int t,x,y;
ll z;
cin>>t;
while(t--){
scanf("%d%d%d",&n,&m,&k);
init();
for(int i=0;i<m;i++){
scanf("%d%d%lld",&x,&y,&z);
add(x,y,z);
}
dij(1);
printf("%lld\n",dp[n][k]);
}
return 0;
}