版权声明:未经本蒟蒻同意,请勿转载本蒻博客 https://blog.csdn.net/wddwjlss/article/details/82229487
题意:一个图,边有边权,给定起点 ,求 到 的路径上最大边权与最小边权的最小比值。
意味着可以跑大概小于 的算法,所以我们将边根据边权从小到大排序后,枚举每一条边作为最小边,枚举大于等于这条边的所有边,通过并查集进行合并,当s和t联通时求出此时的最大边权与最小边权的比值,不断更新答案即可。
#include<bits/stdc++.h>
using namespace std;
struct node
{
int x,y,d;
}e[1001000];
int n,m,s,t,f[1001000],maxn,minn;
double ep=99999;
int find(int x)
{
if(x==f[x])
return x;
else
{
f[x]=find(f[x]);
return f[x];
}
}
bool cmp(node n1,node n2)
{
return n1.d<n2.d;
}
int gcd(int a,int b)
{
if(b==0)
return a;
else
return gcd(b,a%b);
}
int main()
{
cin>>n>>m;
for(int i=1;i<=m;++i)
scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].d);
cin>>s>>t;
sort(e+1,e+m+1,cmp);
for(int i=1;i<=m;++i)
{
bool flag=0;
for(int j=1;j<=n;++j)
f[j]=j;
int u,v;
u=v=e[i].d;
for(int j=i;j<=m;++j)
{
int fx=find(e[j].x);
int fy=find(e[j].y);
if(fx!=fy)
{
f[fx]=fy;
v=e[j].d;
}
if(find(s)==find(t))
{
flag=1;
break;
}
}
if(double(v)/double(u)<ep&&flag)
{
ep=double(v)/double(u);
maxn=v;
minn=u;
}
}
if(!minn)
{
cout<<"IMPOSSIBLE";
return 0;
}
if(ep!=int(ep))
{
int c1=gcd(maxn,minn);
maxn/=c1;
minn/=c1;
cout<<maxn<<"/"<<minn;
return 0;
}
cout<<ep;
return 0;
}