P2502 [HAOI2006]旅行——暴力和并查集的完美结合

时间:2023-03-10 01:58:00
P2502 [HAOI2006]旅行——暴力和并查集的完美结合

P2502 [HAOI2006]旅行

一定要看清题目数据范围再决定用什么算法,我只看着是一个蓝题就想到了记录最短路径+最小生成树,但是我被绕进去了;

看到只有5000的边,我们完全可以枚举最小边和最大边,判断起点和终点是否连通用并查集维护一下就好了;

分数约分一定要仔细想想,

an1==ans2的时候我直接printf("%d",ans1)了,(劝退到小学)

gcd自己写一个吧,(图省事用__gcd()在洛谷水一水也不是不可以吧)

 #include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=;
struct node
{
int x,y,z; bool operator < (const node &we)const
{
return z<we.z;
}
}f[maxn]; int n,m; int father[maxn]; int getfather(int x)
{
if(father[x]==x) return x;
father[x]=getfather(father[x]);
return father[x];
} void merging(int x,int y)
{
father[getfather(x)]=getfather(y);
} int s,t; double ans=1e9; int ans1,ans2; int gcd(int a,int b)
{
return b==?a:gcd(b,a%b);
} int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++) father[i]=i;
for(int i=;i<=m;i++)
{
scanf("%d%d%d",&f[i].x,&f[i].y,&f[i].z);
merging(f[i].x,f[i].y);
} scanf("%d%d",&s,&t); if(getfather(s)!=getfather(t))
{
printf("IMPOSSIBLE\n");
return ;
}
sort(f+,f+m+);
for(int i=;i<=m;i++)
{
for(int k=;k<=n;k++) father[k]=k;
for(int j=i;j<=m;j++)
{
merging(f[j].x,f[j].y);
if(getfather(s)==getfather(t))
{
double qw=(double)f[j].z/(double)f[i].z;
if(qw<ans)
{
ans=qw;
ans1=f[j].z;ans2=f[i].z;
}
break;
}
}
} if(ans1==ans2)
{
printf("");
}
else
{
int we=gcd(ans1,ans2);
if(ans2/we==) printf("%d",ans1/we);
else printf("%d/%d\n",ans1/we,ans2/we);
}
return ;
}