在线评测:
http://codevs.cn/problem/3027/
整体思路:
我们可以先把边排序,然后我们想一下,我们要求一条路,这条路上的最大值和最小值的比值最小,那么显然,我们应该是最大值一定的情况下,最小值尽可能的大。所以我们排完序之后,我们从长边到短边开始枚举最大边,然后我们从这条边开始往下枚举,每次把边的两点联通,然后判断起点终点是否联通,如果联通,则用当前选取的最大边和最小边尝试更新答案。最后求出最优情况下最大边和最小边的大小之后,如果不能整除,gcd一下搞成分数就行了!
失误之处:
我开了一个全局变量minn,来尝试记录当当前最大边为某边时,最小边的权值,然而我没有在每次枚举最大边后将其清零,在判断是否更新答案的时候也没有进行判断当前情况下到底图是否联通,于是存在枚举这个最大边往下根本无法联通,但我还调用了以前的minn来进行计算,最后算出了一些远远小于1的值。实在是一个很大的失误!!!!
体会心得:
一定要考虑会不会误用到上次循环遗留的变量。
不要过于追求开全局变量,适当使用局部变量有时候更能提醒自己进行初始化~~
AC代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
#include <cstdio> #include <cmath> #include <cstring> #include <algorithm> using namespace std; struct lx { int x, y,w; }; bool operator < ( const lx &x, const lx &y) { return x.w > y.w; } int n,m,s,t,fa[1000],size[1000]; int maxn,minn,amaxn,aminn; double pmin; lx sz[10001]; bool lt; int getfa( int x) { if (fa[x] == x) return x; return fa[x] = getfa(fa[x]); } void merge( int x, int y) { if (getfa(x) == getfa(y)) return ; int s1 = getfa(x),s2 = getfa(y); if (size[s1] < size[s2]) { fa[s1] = s2; size[s2] += size[s1]; } else { fa[s2] = s1; size[s1] += size[s2]; } } void init() { for ( int i = 1;i <= n;i++) fa[i] = i,size[i] = 1; } int gcd( int x, int y) { return !y ? x :gcd(y,x % y); } int main() { pmin = 9999999999999.0; scanf ( "%d%d" ,&n,&m); for ( int i = 1;i <= m;i++) { scanf ( "%d%d%d" ,&sz[i].x,&sz[i].y,&sz[i].w); } scanf ( "%d%d" ,&s,&t); sort(sz+1,sz+m+1); for ( int i = 1;i < m;i++) { init(); maxn = sz[i].w; merge(sz[i].x,sz[i].y); if (getfa(s) == getfa(t)) { amaxn = sz[i].w; aminn = sz[i].w; lt = true ; break ; } minn = 0; //就是开始在这个位置没有初始化 for ( int j = i+1;j <= m;j++) { merge(sz[j].x,sz[j].y); if (getfa(s) == getfa(t)) { lt = true ; minn = sz[j].w; break ; } } double t1 = maxn,t2 = minn; if (minn) //这个位置也没有判0 if ((t1 / t2) < pmin) { pmin = t1 / t2; amaxn = maxn; aminn = minn; } } if (!lt) printf ( "IMPOSSIBLE\n" ); else { if (!(amaxn % aminn)) printf ( "%d\n" ,amaxn / aminn); else { int tp = gcd(amaxn,aminn); printf ( "%d/%d\n" ,amaxn/tp,aminn/tp); } } return 0; } |