[BZOJ1050][HAOI2006]旅行comf 枚举+并查集

时间:2023-01-28 22:41:55

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1050

将边排序,枚举边权最小的边,依次加边直到S和T连通,更新答案。

 #include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int inline readint(){
int Num;char ch;
while((ch=getchar())<''||ch>'');Num=ch-'';
while((ch=getchar())>=''&&ch<='') Num=Num*+ch-'';
return Num;
}
int N,M,S,T;
struct EDGE{
int u,v,w;
bool operator < (const EDGE &_)const{
return w<_.w;
}
}edge[];
int fa[];
int inline Getfa(int x){
return fa[x]==x?x:fa[x]=Getfa(fa[x]);
}
int inline Gcd(int a,int b){
return !b?a:Gcd(b,a%b);
}
int main(){
N=readint();
M=readint();
for(int i=;i<=M;i++){
edge[i].u=readint();
edge[i].v=readint();
edge[i].w=readint();
}
sort(edge+,edge++M);
S=readint();
T=readint();
int ansu=,ansd=;
for(int i=;i<=M;i++){
for(int j=;j<=N;j++) fa[j]=j;
int mx;
for(int j=i;j<=M;j++){
int fx=Getfa(edge[j].u),
fy=Getfa(edge[j].v);
if(fx==fy) continue;
mx=edge[j].w;
fa[fx]=fy;
if(Getfa(S)==Getfa(T)) break;
}
if(Getfa(S)!=Getfa(T)) break;
if(mx*ansd<ansu*edge[i].w){
ansu=mx;
ansd=edge[i].w;
}
}
if(ansu==){
puts("IMPOSSIBLE");
return ;
}
int gcd=Gcd(ansu,ansd);
ansu/=gcd;
ansd/=gcd;
if(ansd>) printf("%d/%d\n",ansu,ansd);
else printf("%d\n",ansu);
return ;
}