思路:注意到M才5000,所以直接枚举最小边,然后用类似并查集的方法来计算最小比值
#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 5005;
struct Edge{int u,v,w;}e[maxn];
bool cmp(Edge a,Edge b){return a.w<b.w;}
int fa[maxn];
int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
int n,m,s,t;
void init(){for(int i = 0;i<=n;i++)fa[i]=i;}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
double ans = 1e9;
init();
for(int i = 1;i<=m;i++)
scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
scanf("%d%d",&s,&t);
sort(e+1,e+1+m,cmp);
int fenzi=1e9,fenmu=1;
for(int i = 1;i<=m;i++)
{
init();
int j;
for(j = i;j<=m;j++)
{
int uu = find(e[j].u);
int vv = find(e[j].v);
if(uu!=vv)
fa[uu]=vv;
//fa[find(e[j].u)]=fa[find(e[j].v)];
if(find(s)==find(t))
break;
}
if(find(s)!=find(t))
{
if(i==1)
{
puts("No Answer");
return 0;
}
else
break;
}
if(fenzi*e[i].w >= fenmu*e[j].w)
fenzi = e[j].w,fenmu = e[i].w;
}
printf("%.2f\n",1.0*fenzi/fenmu);
}
}
一个无向图有n个点和m条边,每条边有权值。两点间的路径权值为这条路径上的最大边权和最小边权的比值。
给定一个起点和一个终点,问从起点到终点的路径中,权值最小的比值是多少。
如果起点和终点无法联通,则输出“No Answer”(结果不带引号)。
输出的比值结果严格保留两位小数。
输入第一行为两个整数,n(1<n≤500)和m(1≤m≤5000)表示图中点的数量和双向边的数量。接下来每行3个整数x,y(1≤x,y≤n),p(0<p<30000)表示点x和点y之间有一条双向边,权值为p。第m+1行为两个整数s,t(1≤s,t≤n, s不等于t),表示起点和终点。
输出仅一个数,表示最小的比值,结果保留两位小数。
样例输入
3 3 1 2 10 1 2 5 2 3 8 1 3
样例输出
1.25