dijkstra算法的一种变形吧
题目要求的是最长路的最小值,所以用二分枚举最长路,
注意要改变一下松弛的条件:只对满足权值小于我们枚举的最长路的值得边进行松弛。
代码如下:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<algorithm>
using namespace std;
#define INF 1<<30
#define Max 55550
int u[Max],v[Max],w[Max],d[Max];
int first[Max],next[Max],e,n,m;
typedef pair<int,int>pii;
priority_queue<pii,vector<pii>,greater<pii> >q;
void dijkstra(int s,int mid)
{
int i,j,k;
for(i=1;i<=n;i++)
d[i]=INF;
d[s]=0;
q.push(make_pair(d[s],s));
while(!q.empty())
{
while(!q.empty()&&q.top().first>d[q.top().second])
q.pop();
if(q.empty())
return ;
pii u=q.top();
q.pop();
int x=u.second;
for(int e=first[x];e!=-1;e=next[e])
if(w[e]<=mid)
if(d[v[e]]>d[x]+w[e])
{
d[v[e]]=d[x]+w[e];
q.push(make_pair(d[v[e]],v[e]));
}
}
}
void Init()
{
memset(first,-1,sizeof(first));
e=0;
}
void add_e(int a,int b,int c)
{
u[e]=a;v[e]=b;w[e]=c;
next[e]=first[a];
first[a]=e++;
}
int main()
{
int A,B,i,j;
while(scanf("%d%d%d%d",&n,&m,&A,&B)!=EOF)
{
Init();
for(i=0;i<m;i++)
{
int k1,k2,cost;
scanf("%d%d%d",&k1,&k2,&cost);
add_e(k1,k2,cost);
add_e(k2,k1,cost);
}
int l=0,r=10000,ans;
while(l<=r)
{
int mid=(l+r)/2;
dijkstra(A,mid);
if(d[B]<INF)
r=mid-1,ans=d[B];
else
l=mid+1;
}
printf("%d\n",ans);
}
return 0;
}