BZOJ1050 [HAOI2006] 旅行comf
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1050
Description
给你一个无向图,N(N<=500)个顶点, M(M<=5000)条边,每条边有一个权值Vi(Vi<30000)。给你两个顶点S和T,求一条路径,使得路径上最大边和最小边的比值最小。如果S和T之间没有路径,输出”IMPOSSIBLE”,否则输出这个比值,如果需要,表示成一个既约分数。 备注: 两个顶点之间可能有多条路径。
Input
第一行包含两个正整数,N和M。 下来的M行每行包含三个正整数:x,y和v。表示景点x到景点y之间有一条双向公路,车辆必须以速度v在该公路上行驶。 最后一行包含两个正整数s,t,表示想知道从景点s到景点t最大最小速度比最小的路径。s和t不可能相同。
Output
如果景点s到景点t没有路径,输出“IMPOSSIBLE”。否则输出一个数,表示最小的速度比。如果需要,输出一个既约分数。
并查集+排序,将边按照权值从小到大排序,枚举两条边,用并查集判断起点和终点之间的连通性。
这道题跟CodeVS1001 舒适的路线是同一道。
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #define rep(i,l,r) for(int i=l; i<=r; i++) 6 #define clr(x,y) memset(x,y,sizeof(x)) 7 #define travel(x) for(int i=last[x]; i; i=edge[i].pre) 8 using namespace std; 9 const int INF = 0x3f3f3f3f; 10 const int maxn = 510; 11 struct Edge{ 12 int from,to,cost; 13 }edge[5010]; 14 int n,m,x,y,now,s,t,ans1,ans2,fa[maxn]; 15 inline bool cmp(const Edge &x, const Edge &y){ 16 return x.cost < y.cost; 17 } 18 inline int read(){ 19 int ans = 0, f = 1; 20 char c = getchar(); 21 while (!isdigit(c)){ 22 if (c == '-') f = -1; 23 c = getchar(); 24 } 25 while (isdigit(c)){ 26 ans = ans * 10 + c - '0'; 27 c = getchar(); 28 } 29 return ans * f; 30 } 31 int gcd(int x,int y){ 32 return y ? gcd(y,x%y) : x; 33 } 34 int getfa(int x){ 35 return fa[x] == x ? x : fa[x] = getfa(fa[x]); 36 } 37 int main(){ 38 n = read(); m = read(); 39 rep(i,1,m){ 40 edge[i].from = read(); edge[i].to = read(); edge[i].cost = read(); 41 } 42 s = read(); t = read(); 43 sort(edge+1,edge+m+1,cmp); 44 double rate = INF * 1.0; 45 rep(start,1,m){ 46 rep(i,1,n) fa[i] = i; now = 0; 47 rep(i,start,m){ 48 x = getfa(edge[i].from); y = getfa(edge[i].to); 49 fa[x] = y; 50 if (getfa(s) == getfa(t)){ 51 now = i; break; 52 } 53 } 54 if (!now) break; 55 if (edge[now].cost * 1.0 / edge[start].cost < rate){ 56 rate = edge[now].cost * 1.0 / edge[start].cost; 57 ans1 = edge[now].cost; ans2 = edge[start].cost; 58 } 59 } 60 if (rate == INF) printf("IMPOSSIBLE\n"); 61 else if (!(ans1%ans2)) printf("%d\n",ans1/ans2); 62 else printf("%d/%d\n",ans1/gcd(ans1,ans2),ans2/gcd(ans1,ans2)); 63 return 0; 64 }