思路:注意到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