链接
http://www.lydsy.com/JudgeOnline/problem.php?id=1050
题解
1A系列。
挖个坑,今天要A七道题。(1/7)
这道题目还是挺有意思的,先把边按边权排个序,然后枚举min边,再枚举max边(都是按从小到大枚举的),用并查集维护连通性,当加入一条边使S和T刚好联通时,就可以更新答案。
代码
//暴力枚举+并查集
#include <cstdio>
#include <algorithm>
#include <queue>
#define maxn 100000
#define inf 0x3f3f3f3f
using namespace std;
int N, M, u[maxn], v[maxn], w[maxn], fz, fm, lim, vis[maxn], f[maxn], num[maxn], S, T;
double ans=1e60;
inline bool cmp(int a, int b){return w[a]<w[b];}
void input()
{
int i, j;
scanf("%d%d",&N,&M);
for(i=1;i<=M;i++)scanf("%d%d%d",u+i,v+i,w+i);
scanf("%d%d",&S,&T);
for(i=1;i<=M;i++)num[i]=i;
sort(num+1,num+M+1,cmp);
}
int find(int x){return f[x]==x?x:f[x]=find(f[x]);}
inline void merge(int a, int b){f[find(a)]=find(b);}
void work()
{
int i, j;
double a, b;
for(i=1;i<=M;i++)
{
for(j=1;j<=N;j++)f[j]=j;
for(j=i;j<=M;j++)
{
merge(u[num[j]],v[num[j]]);
if(find(S)==find(T))
{
a=w[num[j]], b=w[num[i]];
if(a/b<ans)ans=a/b,fz=a,fm=b;
break;
}
}
}
}
int gcd(int a, int b){return !b?a:gcd(b,a%b);}
int main()
{
input();
work();
if(fz==0)printf("IMPOSSIBLE");
else
{
int d=gcd(fz,fm);
fz/=d, fm/=d;
printf("%d",fz);
if(fm>1)printf("/%d",fm);
}
return 0;
}