ACM-ICPC 2018南京赛区网络预赛 L.Magical Girl Haze
Problem Description
There are NN cities in the country, and MM directional roads from u to 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 MM 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
题目来源
ACM-ICPC 2018 南京赛区网络预赛
题意
T组输入
N、M、K,分别代表城市数、路径数、可以选择把K条路的长度变为0
之后M行, u、v、c代表从城市 u 到 城市 v 的路径长度为 c(单向边)
问从城市 1 到城市N的最短路
数据范围:
1<=T<=5
N<=100000
M<=20000
K<=10
0<=C<=1e9
思路
多层迪杰斯特拉最短路,用优先队列优化,前向星存图
AC代码
#include <bits/stdc++.h>
#define maxlen 1e15
using namespace std;
const int maxn=1e5+10;
typedef long long ll;
struct node{
int u,v,ne;
ll w;
}e[maxn+maxn];
struct qnode{
int v;
ll w;
qnode(int _v,ll _w):v(_v),w(_w){}
bool operator < (const qnode &a)const{
return w>a.w;
}
};
int n,m,k,tot;
int head[maxn];
ll d[maxn][15]; //d[i][j]表示从城市1到城市i,把j条路的长度变为0的最小长度
void add(int u,int v,ll w) //前向星
{
e[tot].u=u;
e[tot].v=v;
e[tot].w=w;
e[tot].ne=head[u];
head[u]=tot++;
}
void dij(int s)
{
int i,j;
for(i=0;i<=k;i++){
d[s][i]=0;
}
priority_queue<qnode>q; //优先队列
qnode a(s,0);
q.push(qnode(s,0));
while(!q.empty()){
a=q.top();
q.pop();
int u=a.v;
for(i=head[u];i!=-1;i=e[i].ne){
int v=e[i].v;
ll w=e[i].w;
for(j=0;j<=k;j++){
if(d[v][j]>d[u][j]+w){ //同层路径长度松弛
d[v][j]=d[u][j]+w;
q.push(qnode(v,d[v][j]));
}
if(j<k&&d[v][j+1]>d[u][j]){ //不同层路径长度松弛
d[v][j+1]=d[u][j];
q.push(qnode(v,d[v][j+1]));
}
}
}
}
}
int main()
{
int t;
scanf("%d", &t);
while(t--){
tot=0;
memset(head,-1,sizeof(head));
scanf("%d %d %d", &n,&m,&k);
int i,j;
for(i=0;i<=n;i++){
for(j=0;j<=k;j++){
d[i][j]=maxlen;
}
}
int u,v;
ll w;
for(i=1;i<=m;i++){
scanf("%d %d %lld",&u,&v,&w);
add(u,v,w);
}
dij(1);
ll ans=maxlen;
for(i=0;i<=k;i++){
ans=min(ans,d[n][i]);
}
printf("%lld\n",ans);
}
return 0;
}