COJ1307 City Tour 最短路+二分

来源:互联网 发布:usbkiller算法注册机 编辑:程序博客网 时间:2024/06/10 07:08

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 100010typedef 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;  }  


0 0
原创粉丝点击