链接:https://ac.nowcoder.com/acm/contest/1069/F
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld
题目描述
Farmer John wants to set up a telephone line at his farm. Unfortunately, the phone company is uncooperative, so he needs to pay for some of the cables required to connect his farm to the phone system.
There are N (1 ≤ N ≤ 1,000) forlorn telephone poles conveniently numbered 1…N that are scattered around Farmer John’s property; no cables connect any them. A total of P (1 ≤ P ≤ 10,000) pairs of poles can be connected by a cable; the rest are too far apart.
The i-th cable can connect the two distinct poles Ai and Bi, with length Li (1 ≤ Li ≤ 1,000,000) units if used. The input data set never names any {Ai, Bi} pair more than once. Pole 1 is already connected to the phone system, and pole N is at the farm. Poles 1 and N need to be connected by a path of cables; the rest of the poles might be used or might not be used.
As it turns out, the phone company is willing to provide Farmer John with K (0 ≤ K < N) lengths of cable for free. Beyond that he will have to pay a price equal to the length of the longest remaining cable he requires (each pair of poles is connected with a separate cable), or 0 if he does not need any additional cables.
Determine the minimum amount that Farmer John must pay.
输入描述:
- Line 1: Three space-separated integers: N, P, and K
- Lines 2…P+1: Line i+1 contains the three space-separated integers: Ai, Bi, and Li
输出描述: - Line 1: A single integer, the minimum amount Farmer John can pay. If it is impossible to connect the farm to the phone company, print -1.
示例1
输入
复制
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
说明
There are 5 poles. Pole 1 cannot be connected directly to poles 4 or 5. Pole 5 cannot be connected directly to poles 1 or 3. All other pairs can be connected. The phone company will provide one free cable.
If pole 1 is connected to pole 3, pole 3 to pole 2, and pole 2 to pole 5 then Farmer John requires cables of length 4, 3, and 9. The phone company will provide the cable of length 9, so the longest cable needed has length 4.
题意:
大概题意就是,给一些点之间建边的花费,要使1与n连通,你建立的1–〉n这条路上,有k条边的花费(任意k条)可以报销(原题就是电力公司会免费提供),要你求解要自己出钱的最大一条边的权值最小是多少。
很明显就是求解第k+1大最小。
转换一下就是最多有k条边比ans大。
为什么是最多k条呢?
因为1–〉n这条路可能不足k条边就可以使它相连(此时自己不用出钱)
ans一定是唯一的一个值
所以本题:用二分ans+spfa来做
spfa中dis数组中记录的是1到各点有多少个点比二分的ans大
当dis[n]<=k说明此时二分的ans大了,二分ans要向前移动
AC_code:
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
const int MAXN = 1e4+5;
struct Edge
{
int to;
int val;
Edge(int t,int v):to(t),val(v){
}
};
vector<Edge>vec[MAXN];
bool isIn[MAXN];
int dis[MAXN];
int n,p,k;
bool spfa(int mid)
{
for(int i = 1; i<= n; i++)
{
isIn[i] = false;
dis[i] = INF;
}
dis[1] = 0;
queue<int>q;
isIn[1] = true;
q.push(1);
while(!q.empty())
{
int k = q.front();
q.pop();
isIn[k] = false;
int iSize = vec[k].size();
for(int i = 0; i < iSize; i++)
{
int t = vec[k][i].to;
int v = vec[k][i].val > mid;
if(dis[t] > dis[k] + v)
{
dis[t] = dis[k] + v;
if(!isIn[t])
{
isIn[t] = true;
q.push(t);
}
}
}
}
return dis[n] <= k;
}
int main()
{
scanf("%d%d%d",&n,&p,&k);
int x,y,v;
for(int i = 0; i < p; i++)
{
scanf("%d%d%d",&x,&y,&v);
vec[x].push_back(Edge(y,v));
vec[y].push_back(Edge(x,v));
}
int l = 0,r = 1e6;
int res = -1;
while(l <= r)
{
int mid = (l+r)>>1;
if(spfa(mid))
{
res = mid;
r = mid - 1;
}
else
{
l = mid + 1;
}
}
printf("%d\n",res);
return 0;
}