分析
本题主要就是一个转化
当我们看到数据范围,就可以大胆猜测较高复杂度的算法
因为维护最大值比较麻烦
我们考虑用二分答案限制最大值
然后就可以顺理成章的想出
将的路径长度标为1
跑一个最短路
如果最后的Dist[T]那么这就是一个可行的解
以此二分即可求得答案
代码
//P1948
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#define LL long long
#define Cl(X,Y) memset((X),(Y),sizeof(X))
#define FOR(i,A,B) for(int i=A;i<=B;i++)
#define BOR(i,A,B) for(int i=A;i>=B;i--)
#define INF 0x3f3f3f3f
using namespace std;
const int MaxN=2e4+10;
int Next[MaxN<<1],Head[MaxN],End[MaxN<<1],Cur,Val[MaxN<<1];
int Total,Side,Limit,cnt,h[1005],Dist[1005],Mine[1005];
bool Jud[1005];
inline void Add_Edge(int u,int v,int w) {
Next[++Cur]=Head[u];
Head[u]=Cur;
End[Cur]=v;
Val[Cur]=w;
}
inline bool check(int x) {
Cl(Dist,0x3f);
int R=0,L=1,i,New,s;
Dist[1]=0;
Mine[R]=1;
Jud[1]=1;
while(R!=L) {
New=Mine[R];R++;
if(R==1001)R=0;
i=h[New];
for(int i=Head[New];i;i=Next[i]) {
if(Val[i]>x) s=Dist[New]+1;
else s=Dist[New];
if(s<Dist[End[i]]) {
Dist[End[i]]=s;
if(!Jud[End[i]]) {
Mine[L++]=End[i];
Jud[End[i]]=1;
if(L==1001)L=0;
}
}
}
Jud[New]=0;
}
if(Dist[Total]<=Limit)return 1;
return 0;
}
int main() {
scanf("%d %d %d",&Total,&Side,&Limit);
int u,v,L,l=0,r=1000000,mid;
FOR(i,1,Side) {
scanf("%d %d %d",&u,&v,&L);
Add_Edge(u,v,L);
Add_Edge(v,u,L);
}
int Ans=-1;
while(l<=r) {
mid=(l+r)>>1;
if(check(mid)){r=mid-1;Ans=mid;}
else l=mid+1;
}
printf("%d\n",Ans);
system("pause");
return 0;
} 
京公网安备 11010502036488号