[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<N≤500
1≤x,y≤N,0<v<30000,x≠y
0<M≤5000
按边权排序
枚举i,从第i条边开始加,直到s,t连通,统计答案
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 using namespace std; 7 struct Edge 8 { 9 int u,v,d; 10 }e[10001]; 11 int set[5001],n,m,s,t,fz,fm; 12 double ans; 13 int gcd(int a,int b) 14 { 15 if (!b) return a; 16 return gcd(b,a%b); 17 } 18 bool cmp(Edge a,Edge b) 19 { 20 return a.d<b.d; 21 } 22 int find(int x) 23 { 24 if (set[x]!=x) set[x]=find(set[x]); 25 return set[x]; 26 } 27 int main() 28 {int i,j; 29 cin>>n>>m; 30 for (i=1;i<=m;i++) 31 { 32 scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].d); 33 } 34 sort(e+1,e+m+1,cmp); 35 ans=2e9; 36 cin>>s>>t; 37 for (i=1;i<=m;i++) 38 { 39 for (j=0;j<=n;j++) 40 set[j]=j; 41 set[e[i].u]=e[i].v; 42 if (find(s)==find(t)) 43 { 44 ans=1;fz=1;fm=1; 45 break; 46 } 47 for (j=i+1;j<=m;j++) 48 { 49 int p=find(e[j].u),q=find(e[j].v); 50 if (p!=q) 51 { 52 set[p]=q; 53 } 54 if (find(s)==find(t)) 55 { 56 if (ans>(double)e[j].d/e[i].d) 57 ans=(double)e[j].d/e[i].d,fz=e[j].d,fm=e[i].d; 58 break; 59 } 60 } 61 } 62 if (ans==2e9) cout<<"IMPOSSIBLE\n"; 63 else 64 { 65 int d=gcd(fz,fm); 66 fz/=d;fm/=d; 67 if (fm==1) printf("%d\n",fz); 68 else printf("%d/%d\n",fz,fm); 69 } 70 }