【解题思路】
先把边按边权排序,然后O(m)暴力枚举最小边,对于每条最小边,将比其大的边按序加入直到起终点连通,此时最大边权/最小边权即为选择该最小边情况下的最小比值。复杂度O(m(m+n)α(n))。
【参考代码】
1 #include <bits/stdc++.h> 2 #define range(i,c,o) for(register int i=(c);i<(o);++i) 3 #define dange(i,c,o) for(register int i=(c);i>(o);--i) 4 5 //#define __debug 6 #ifdef __debug 7 #define Function(type) type 8 #define Procedure void 9 #else 10 #define Function(type) __attribute__((optimize("-O2"))) inline type 11 #define Procedure __attribute__((optimize("-O2"))) inline void 12 #endif 13 14 #ifdef __int128_t 15 typedef __int128_t integer; 16 #else 17 typedef long long integer; 18 #endif 19 20 using namespace std; 21 22 //quick_io { 23 Function(integer) getint() 24 { 25 char c=getchar(); for(;!isdigit(c)&&c!='-';c=getchar()); 26 short s=1; for(;c=='-';c=getchar()) s*=-1; integer r=0; 27 for(;isdigit(c);c=getchar()) (r*=10)+=c-'0'; return s*r; 28 } 29 //} quick_io 30 31 struct edge 32 { 33 int fr,to,vl; 34 edge(const int&f=0,const int&t=0,const int&v=0): 35 fr(f),to(t),vl(v) {} 36 Procedure input() {fr=getint(),to=getint(),vl=getint();} 37 Function(bool) operator<(const edge&t)const 38 { 39 return vl<t.vl; 40 } 41 }edg[5005]; 42 43 int fat[505]; 44 int getfa(const int&x) {return fat[x]==x?x:fat[x]=getfa(fat[x]);} 45 46 int main() 47 { 48 int n=getint(),m=getint(); range(i,0,m) edg[i].input(); 49 int S=getint(),T=getint(),up=0,down=0; sort(edg,edg+m); 50 range(i,0,m) 51 { 52 range(j,1,n+1) fat[j]=j; 53 range(j,i,m) 54 { 55 fat[getfa(edg[j].fr)]=getfa(edg[j].to); 56 if(getfa(S)==getfa(T)) 57 { 58 if(!up||up*edg[i].vl>down*edg[j].vl) 59 { 60 up=edg[j].vl,down=edg[i].vl; 61 } 62 break; 63 } 64 } 65 } 66 if(!up) return puts("IMPOSSIBLE"),0; 67 int g=__gcd(up,down); up/=g,down/=g; 68 return down==1?printf("%d\n",up):printf("%d/%d\n",up,down),0; 69 }
We Secure, We Contain, We Protect.