天天看點

[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】

【樣例輸出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 }