Description
Alice想要从城市A出发到城市B,由于Alice最近比较穷(不像集训队陈兴老师是个rich second),所以只能选择做火车从A到B。不过Alice很讨厌坐火车,火车上人比较多,比较拥挤,所以Alice有很严格的要求:火车的相邻两站间的最大距离尽可能的短,这样Alice就可以在停站的时候下车休息一下。当然Alice希望整个旅途比较短。
Input
有多组测试数据。
每组测试数据的第一行有两个整数N,M,A,B(N<=2000, M<=50000, N >=2, A,B<=N),其中N是城市的个数,M是城市间通火车的个数。
A,B是Alice起始的城市与目的地城市,城市的标号从1开始。
接下来的M行每行三个整数u,v,w表示从u到v和从v到u有一条铁路,距离为w, u,v<=N, w<=10000。
Output
对于每组测试数据输出满足Alice要求的从A到B的最短距离。
思路:一开始以为是求只要从A点出发,找从该点出发最小值。后来讲评时,再仔细研究了下题目,发现其要求的是相邻两站的最大距离尽可能短,也是说所有边都要小于一个值(最大距离),且要求从A点到B点要有解。这样,题目也就不难了。。总之,理解题意还是比较重要的。
#include<stdio.h>
#include<string.h>
#include<queue>
#include<algorithm>
using namespace std;
#define maxn 2010
#define maxm 100010
typedef pair<int,int> pii;
priority_queue<pii,vector<pii>,greater<pii> >p;
int first[maxn],next[maxm],n,m,s,t,tot,ans,d[maxn];
struct node
{
int v,w;
}edge[maxm];
bool dj(int mid)
{
memset(d,0x3f,sizeof(d));
d[s]=0;
p.push(make_pair(0,s));
while(!p.empty())
{
pii cur=p.top();
p.pop();
if(cur.first>d[cur.second])continue;
for(int i=first[cur.second];i!=-1;i=next[i])
{
if(edge[i].w<=mid)
if(d[edge[i].v]>d[cur.second]+edge[i].w)
{
d[edge[i].v]=d[cur.second]+edge[i].w;
p.push(make_pair(d[edge[i].v],edge[i].v));
}
}
}
if(d[t]!=0x3f3f3f3f)return true;
else return false;
}
void add_edge(int u,int v,int w)
{
edge[tot].v=v;edge[tot].w=w;
next[tot]=first[u];first[u]=tot++;
}
int main()
{
while(~scanf("%d%d%d%d",&n,&m,&s,&t))
{
int i,j,k,u,v,w;
memset(first,-1,sizeof(first));
tot=0;
for(i=1;i<=m;i++)
{
scanf("%d%d%d",&u,&v,&w);
add_edge(u,v,w);
add_edge(v,u,w);
}
int front=0,rear=10001,mid;
while(front<rear)
{
mid=front+(rear-front)/2;
if(dj(mid)){rear=mid;ans=d[t];}
else front=mid+1;
}
printf("%d\n",ans);
}
return 0;
}