通信线路

题目描述

在郊区有 N 座通信基站,P 条 双向 电缆,第 i 条电缆连接基站 Ai 和 Bi。

特别地,1 号基站是通信公司的总站,N 号基站位于一座农场中。

现在,农场主希望对通信线路进行升级,其中升级第 i 条电缆需要花费 Li。

电话公司正在举行优惠活动。

农产主可以指定一条从 1 号基站到 N 号基站的路径,并指定路径上不超过 K 条电缆,由电话公司免费提供升级服务。

农场主只需要支付在该路径上剩余的电缆中,升级价格最贵的那条电缆的花费即可。

求至少用多少钱可以完成升级。

输入格式
第 1 行:三个整数 N,P,K。

第 2..P+1 行:第 i+1 行包含三个整数 Ai,Bi,Li。

输出格式
包含一个整数表示最少花费。

若 1 号基站与 N 号基站之间不存在路径,则输出 −1。

数据范围
0≤K<N≤1000,
1≤P≤10000,
1≤Li≤1000000
输入样例:
5 7 1
1 2 5
3 1 4
2 4 8
3 2 3
5 2 9
3 4 7
4 5 6
输出样例:
4

Code:

#include <iostream>
#include <algorithm>
#include <queue>
#include <cstring>
#include <cstdlib>

using namespace std;

typedef pair<int,int> PII;

const int N=1005,M=10005,INF=0x3f3f3f3f;

int n,m,K;
int idx,h[N];
int dis[N],cnt[N];
bool st[N];
struct node
{
    int nxt,to,w;
}e[M<<1];
struct Side
{
    int a,b,c;
}E[M];

void add(int nxt,int to,int w)
{
    e[++idx].nxt=h[nxt];
    e[idx].to=to;
    e[idx].w=w;
    h[nxt]=idx;
}
bool check(int mid)
{    
    memset(dis,0x3f,sizeof dis);
    memset(st,0,sizeof st);
    priority_queue<PII,vector<PII>,greater<PII>> q;
    dis[1]=0;
    q.push({0,1});

    while(q.size())
    {
        int u=q.top().second;
        q.pop();

        if(st[u])continue;
        st[u]=1;

        for(int i=h[u];~i;i=e[i].nxt)
        {
            int v=e[i].to;
            int w=(e[i].w>mid);
            if(dis[v]>dis[u]+w)
            {
                dis[v]=dis[u]+w;
                q.push({dis[v],v});
            }
        }
    }
    if(dis[n]<INF)return dis[n]<=K;
    puts("-1");
    exit(0);
}
int main()
{
    cin>>n>>m>>K;

    memset(h,-1,sizeof h);
    for(int i=0;i<m;++i)
    {
        int a,b,c;
        cin>>a>>b>>c;
        add(a,b,c),add(b,a,c);
    }

    int l=0,r=1e6;

    while(l<r)
    {
        int mid=(l+r)>>1;
        if(check(mid))r=mid;
        else l=mid+1;
    }
    cout<<r<<endl;

    return 0;
}
posted @ 2022-10-19 23:03  FighterQ  阅读(71)  评论(0)    收藏  举报