[HAOI2006] 旅行

【题目描述】

 

Z小镇是一个景色宜人的地方,吸引来自各地观光客来此旅游观光。Z小镇附近共有N个景点(编号为1,2,3...N),这些景点被M条道路连接着,所有道路都是双向的,两个景点之间可能有多条道路连接着。也许是为了保护该地的旅游资源,Z小镇有个奇怪的规定,就是对于一条给定的公路Ri,任何在该公路上行驶的车辆速度必须为Vi。速度变化太快使得游客们很不舒服,因此从一个景点前往另一个景点的时候,大家都希望选择行使过程中最大速度和最小速度的比尽可能小的路线,也就是所谓最舒适路线。

 

【输入格式】

 

第一行包括两个整数: N 和 M  

接下来的M行每行包含三个正整数: x,y和v。表示景点x到景点y之间有一条双向公路,车辆必须以速度v在该公路上行驶。最后一行包含两个正整数s,t,表示想知道从景点s到景点t最大最小速度比最小的路径。s和t不可能相同。

 

【输出格式】

 

如果景点s到景点t没有路径,输出“IMPOSSIBLE”。否则输出一个数,表示最小的速度比。如果需要,输出一个既约分数。

 

 

 

【样例输入1】

4 2
1 2 1
3 4 2
1 4


【样例输出1】

IMPOSSIBLE

【样例输入2】

3 3 1 2 10 1 2 5 2 3 8 1 3

【样例输出2】

5/4

【样例输入3】

3 2
1 2 2
2 3 4
1 3

【样例输出3】

2
0<N<=500;0<M<=5000,v<=30000;


题解:
将边从小到大排序,枚举最小速度,然后选大于最小速度的边使s,t联通,统计答案即可
 1 #include <algorithm>
 2 #include <iostream>
 3 #include <cstdlib>
 4 #include <cstring>
 5 #include <cstdio>
 6 #include <cmath>
 7 using namespace std;
 8 const int M=5005;
 9 int gi(){
10     int str=0;char ch=getchar();
11     while(ch>'9' || ch<'0')ch=getchar();
12     while(ch>='0' && ch<='9')str=(str<<1)+(str<<3)+ch-48,ch=getchar();
13     return str;
14 }
15 struct node{
16     int x,y,dis;
17     bool operator <(const node &pp)const{
18         return dis<pp.dis;
19     }
20 }e[M];
21 int n,m,fa[505];
22 int find(int x){
23     return x==fa[x]?x:fa[x]=find(fa[x]);
24 }
25 int fm=100000,fz=1,s,t;
26 bool check(int sta){
27     int x,y,mx=e[sta].dis;
28     for(int i=1;i<=n;i++)fa[i]=i;
29     fa[find(e[sta].y)]=find(e[sta].x);
30     for(int i=sta+1;i<=m;i++){
31         x=e[i].x;y=e[i].y;
32         if(find(s)==find(t))break;
33         if(find(x)==find(y))continue;
34         mx=e[i].dis;fa[find(y)]=find(x);
35     }
36     if(find(s)!=find(t))return false;
37     if(mx*fz<fm*e[sta].dis){
38         fz=e[sta].dis;fm=mx;
39     }
40     return true;
41 }
42 int gcd(int x,int y){return x%y?gcd(y,x%y):y;}
43 void work()
44 {
45     n=gi();m=gi();
46     for(int i=1;i<=m;i++)
47         e[i].x=gi(),e[i].y=gi(),e[i].dis=gi();
48     sort(e+1,e+m+1);
49     s=gi();t=gi();
50     for(int i=1;i<=m;i++){
51         if(!check(i))break;
52     }
53     if(fm==100000){
54         printf("IMPOSSIBLE\n");
55         return ;
56     }
57     if(!(fm%fz)){
58         printf("%d\n",fm/fz);
59         return ;
60     }
61     int ops=gcd(fm,fz);
62     printf("%d/%d\n",fm/ops,fz/ops);
63 }
64 int main()
65 {
66     freopen("comf.in","r",stdin);
67     freopen("comf.out","w",stdout);
68     work();
69     return 0;
70 }

 

 
posted @ 2017-07-19 20:21  PIPIBoss  阅读(218)  评论(0编辑  收藏  举报