1307: City Tour
Time Limit: 1 Sec Memory Limit: 128 MB[Submit][Status][Web Board]
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
思路:这个题出的很好,和13南京网赛的1002很像,容易犯一个小毛病的地方就是加边的时候判断。
#include <iostream> #include <stdio.h> #include <queue> #include <stdio.h> #include <string.h> #include <vector> #include <queue> #include <set> #include <algorithm> #include <map> #include <math.h> #define Max(a,b) ((a)>(b)?(a):(b)) using namespace std ; typedef long long LL ; int N ,M ,Start ,End; struct Edge{ int u ; int v ; int w ; friend bool operator <(const Edge A ,const Edge B){ return A.w<B.w ; } }; Edge edge[50008] ; const int size=2008 ; vector< pair<int,int> >vec[size] ; int father[size] ; void init(){ for(int i=1;i<=N;i++){ father[i]=i ; vec[i].clear() ; } } int find_father(int x){ if(father[x]==x) return x ; else return father[x]=find_father(father[x]) ; } void read(){ for(int i=1 ;i<=M ;i++) scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w) ; } int dist[size] ; bool in_queue[size] ; const int inf=1000000000 ; int spfa(){ queue<int>que ; fill(dist,dist+1+N,inf) ; fill(in_queue,in_queue+1+N,0) ; in_queue[Start]=1 ; dist[Start]=0 ; que.push(Start) ; while(!que.empty()){ int u=que.front() ; que.pop() ; in_queue[u]=0 ; for(int i=0;i<vec[u].size();i++){ int v=vec[u][i].first ; int w=vec[u][i].second ; if(dist[u]+w<dist[v]){ dist[v]=dist[u]+w ; if(!in_queue[v]){ in_queue[v]=1 ; que.push(v) ; } } } } return dist[End] ; } int gao(){ init() ; read() ; sort(edge+1,edge+1+M) ; int u ,v ,w ,f_u ,f_v ,i ,j ; for(i=1;i<=M;i++){ u=edge[i].u ; v=edge[i].v ; w=edge[i].w ; f_u=find_father(u) ; f_v=find_father(v) ; if(f_u!=f_v) father[f_u]=f_v ; vec[u].push_back(make_pair(v,w)) ; vec[v].push_back(make_pair(u,w)) ; f_u=find_father(Start) ; f_v=find_father(End) ; if(f_u==f_v) break ; } for(j=i+1;j<=M;j++){ if(edge[j].w==edge[i].w){ u=edge[j].u ; v=edge[j].v ; w=edge[j].w ; vec[u].push_back(make_pair(v,w)) ; vec[v].push_back(make_pair(u,w)) ; } else break ; } return spfa() ; } int main(){ while(scanf("%d%d%d%d",&N,&M,&Start,&End)!=EOF){ printf("%d ",gao()) ; } return 0 ; }