City Tour

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的最短距离。

 

Sample Input

3 3 1 2
1 2 80
1 3 40
2 3 50
3 3 1 2
1 2 90
1 3 10
2 3 20
4 5 1 4
1 2 8
1 4 9
1 3 10
2 4 7
3 4 8

Sample Output

90
30
15

题意:给定n个点,m条路,求一条从起点至终点的路径使得每段路径最短
题解:根据二分的思想,对图中的边从最大值开始进行二分。然后用spfa算法判断在该权值下能否得到路径进行二分区间取段。
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<queue>
#define inf 10000000
using namespace std;
struct lmx{
    int v;
    int w;
    int pre;
};
lmx lm[50005];
int visit[2005];
int des[2005];
int a[2005];
int n,m,s,e,k;
void addedge(int u,int v,int c)
{
    lm[k].v=v;
 lm[k].w=c;
    lm[k].pre=a[u];
 a[u]=k++;
}
int spfa(int s,int e,int m)
{
 int i;
    for(i=1;i<=n;i++) visit[i]=0;
 for(i=1;i<=n;i++) des[i]=inf; 
    queue<int> q;
 des[s]=0;
 q.push(s);
 while(!q.empty())
 {
  int u=q.front();
  q.pop();
  visit[u]=0;
  for(i=a[u];i!=-1;i=lm[i].pre)
  {
   if(lm[i].w<=m)
   {
    if(des[lm[i].v]>des[u]+lm[i].w)
    {
     des[lm[i].v]=des[u]+lm[i].w;
     if(visit[lm[i].v]==0)
     {
      visit[lm[i].v]=1;
      q.push(lm[i].v);
     }
    }
   }
  }
 }
 return des[e]==inf?0:des[e];
}
int main()
{
    int d,b,c,i;
 while(scanf("%d %d %d %d",&n,&m,&s,&e)!=EOF)
 {
  memset(a,-1,sizeof(a));
  k=0;
        for(i=0;i<m;i++)
  {
   scanf("%d %d %d",&d,&b,&c);
   addedge(d,b,c);
   addedge(b,d,c);
  }
        int l=0,r=10001;
  int mid;
  while(r-l>1)
  {
   mid=(l+r)/2;
   if(spfa(s,e,mid)) r=mid;
   else l=mid;
  }
  printf("%d\n",spfa(s,e,r));
 }
 return 0;
}

转载于:https://www.cnblogs.com/ffhuguang/p/3311701.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值