1050: [HAOI2006]旅行comf

1050: [HAOI2006]旅行comf

链接

分析

  考虑如何统计答案,且复杂度较小,直接搜索是不行的。那么考虑先枚举一条较小的边,然后依次加入比它大的点,一旦ST联通了,那么说明当前比值为 最新加入的边 比 枚举的较小的边,用并查集维护,取最小值。

代码

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4  
 5 inline int read() {
 6     int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
 7     for (;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
 8 }
 9  
10 const int N = 5005;
11  
12 struct Edge{
13     int u,v,w;
14     bool operator < (const Edge &A) const {
15         return w < A.w;
16     }
17 }e[N];
18 int fa[505];
19 int gcd(int a,int b) {
20     if (b == 0) return a;
21     return gcd(b,a%b);
22 }
23 int find(int x) {
24     if (x == fa[x]) return x;
25     return fa[x] = find(fa[x]);
26 }
27  
28 int main() {
29     int n = read(),m = read();
30     for (int i=1; i<=m; ++i) {
31         e[i].u = read(),e[i].v = read(),e[i].w = read();
32     }
33     int S = read(),T = read();
34     int ans1 = -1,ans2 = -1;
35     double ans = 1e9;
36     sort(e+1,e+m+1);
37      
38     for (int i=1; i<=m; ++i) {
39         for (int j=1; j<=n; ++j) fa[j] = j;
40          
41         for (int j=i; j<=m; ++j) {
42             int u = find(e[j].u),v = find(e[j].v);
43             if (u != v) fa[u] = v;
44              
45             if (find(S) == find(T)) {
46                 double t = (1.0 * e[j].w) / (1.0 * e[i].w);
47                 if (t < ans) {
48                     ans = t;ans1 = e[i].w,ans2 = e[j].w;
49                 }
50                 break;
51             }
52         }
53         if (ans1 == -1 && ans2 == -1) {
54             puts("IMPOSSIBLE");return 0;
55         }
56     }
57     int d = gcd(ans1,ans2);
58     ans2 /= d,ans1 /= d;
59     if (ans1 == 1) cout << ans2;
60     else cout << ans2 << "/" << ans1; //居然写成了 cout << ans2/d << "\" << ans1/d !!!     
61     return 0;
62 }
原文地址:https://www.cnblogs.com/mjtcn/p/9266405.html