→题目链接←
二分ans,小于等于ans的边的距离看作0,大于ans的看作1
每次跑一下最短路,dis[n]代表有多少边是需要免费的
所以如果dis[n]<=k,答案可行,否则不可行
别忘了输出-1
代码:
#include<iostream>
#include<cstdio>
#include<vector>
#include<queue>
using namespace std;
struct node{
int to,len;
int now;
};
vector<node>v[10010];
int dis[10010];
bool vis[10010];
int n,m,k;
queue<node>q;
int ans=-1;
void link(int x,int y,int z){
node t;
t.to=y;
t.len=z;
v[x].push_back(t);
t.to=x;
v[y].push_back(t);
}
bool spfa(int x){
for(int i=1; i<=n; i++){
dis[i]=23333;
vis[i]=false;
}
node t;
t.now=1;
t.len=0;
dis[1]=0;
vis[1]=true;
q.push(t);
while(!q.empty()){
t=q.front();
q.pop();
if(t.now==n)continue;
for(int i=0; i<v[t.now].size(); i++){
int to=v[t.now][i].to;
int len=(v[t.now][i].len<=x)?0:1;
if(dis[to]>dis[t.now]+len){
dis[to]=dis[t.now]+len;
if(!vis[to]){
node t1=t;
t1.now=to;
t1.len+=len;
vis[to]=true;
q.push(t1);
}
}
}
vis[t.now]=false;
}
if(dis[n]<=k)return true;
return false;
}
int main(){
scanf("%d%d%d",&n,&m,&k);
for(int i=0; i<m; i++){
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
link(x,y,z);
}
int l=0,r=1000000;
while(l<=r){
int mid=(l+r)/2;
if(spfa(mid))ans=mid,r=mid-1;
else l=mid+1;
}
printf("%d\n",ans);
return 0;
}