ACM-ICPC 2018南京赛区网络预赛 L.Magical Girl Haze

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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值