Title
P1948 [USACO08JAN]Telephone Lines S
Solution
- 二分需要花费的路径的长度 g g g,然后判定的时候,将所有小于等于 g g g的路径赋值为0,否则为1。
- 然后求 1 1 1到 n n n的最短路,如果距离小于等于 k k k则缩小二分右端点,否则扩大二分范围。
Code
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
#define ll long long
#define rep(i,x,y) for(register ll i=x;i<=y;i++)
using namespace std;
ll n,p,k;
struct node{
ll y,z,next;
}a[100001];
ll tot,head[1001],ans=-1,d[1001];
queue<ll>q;
bool b[1001];
void add(ll x,ll y,ll z){
a[++tot]=(node){y,z,head[x]}; head[x]=tot;
}
inline bool spfa(ll mid){
memset(b,0,sizeof(b));
memset(d,0x3f,sizeof(d));
q.push(1); d[1]=0; b[1]=1;
while (q.size()){
ll x=q.front(); q.pop();
for(ll i=head[x];i;i=a[i].next){
ll y=a[i].y;
ll g=a[i].z;
if (g<=mid) g=0; else g=1;
if (g+d[x]<d[y]) {
d[y]=d[x]+g;
if (!b[y]) q.push(y),b[y]=1;
}
}
b[x]=0;
}
if (d[n]<=k) return 1;
else return 0;
}
int main(){
scanf("%lld%lld%lld",&n,&p,&k);
rep(i,1,p){
ll x,y,z;
scanf("%lld%lld%lld",&x,&y,&z);
add(x,y,z); add(y,x,z);
}
ll l=0,r=1000000;
while(l<=r){
ll mid=(l+r)>>1;
if (spfa(mid)) r=mid-1,ans=mid; else l=mid+1;
}
printf("%lld",ans);
}