通信线路
题目描述
在郊区有 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;
}