计蒜客 简单图论(并查集+枚举)

来源:互联网 发布:知的太多所以疯了 编辑:程序博客网 时间:2024/05/29 16:33

思路:注意到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 31 2 101 2 52 3 81 3

样例输出

1.25

0 0
原创粉丝点击