• bzoj1050 旅行comf(并查集)


    题意:

    Description

      给你一个无向图,N(N<=500)个顶点, M(M<=5000)条边,每条边有一个权值Vi(Vi<30000)。给你两个顶点S和T
    ,求一条路径,使得路径上最大边和最小边的比值最小。如果S和T之间没有路径,输出”IMPOSSIBLE”,否则输出
    这个比值,如果需要,表示成一个既约分数。 备注: 两个顶点之间可能有多条路径。

    Input

      第一行包含两个正整数,N和M。下来的M行每行包含三个正整数:x,y和v。表示景点x到景点y之间有一条双向
    公路,车辆必须以速度v在该公路上行驶。最后一行包含两个正整数s,t,表示想知道从景点s到景点t最大最小速
    度比最小的路径。s和t不可能相同。
    1<N<=500,1<=x,y<=N,0<v<30000,0<M<=5000

    Output

      如果景点s到景点t没有路径,输出“IMPOSSIBLE”。否则输出一个数,表示最小的速度比。如果需要,输出一
    个既约分数。

    思路:
    可以排序后枚举最小边,然后暴力最大边,类似克鲁斯卡尔
    /* ***********************************************
    Author        :devil
    ************************************************ */
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <set>
    #include <map>
    #include <string>
    #include <cmath>
    #include <stdlib.h>
    #define inf 0x3f3f3f3f
    #define LL long long
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    #define dec(i,a,b) for(int i=a;i>=b;i--)
    #define ou(a) printf("%d
    ",a)
    #define pb push_back
    #define mkp make_pair
    template<class T>inline void rd(T &x){char c=getchar();x=0;while(!isdigit(c))c=getchar();while(isdigit(c)){x=x*10+c-'0';c=getchar();}}
    #define IN freopen("in.txt","r",stdin);
    #define OUT freopen("out.txt","w",stdout);
    using namespace std;
    const int mod=1e9+7;
    const int N=5e3+10;
    struct wq
    {
        int u,v,w;
    }a[N];
    bool cmp(wq a,wq b)
    {
        return a.w<b.w;
    }
    int n,m,x,y,pre[510],a1,a2,j;
    bool flag;
    int Find(int x)
    {
        return x==pre[x]?x:pre[x]=Find(pre[x]);
    }
    int main()
    {
        rd(n),rd(m);
        rep(i,1,m) rd(a[i].u),rd(a[i].v),rd(a[i].w);
        sort(a+1,a+m+1,cmp);
        rd(x),rd(y);
        rep(i,1,m)
        {
            rep(j,1,n) pre[j]=j;
            for(j=i;j<=m;j++)
            {
                int fa=Find(a[j].u),fb=Find(a[j].v);
                if(fa==fb) continue;
                pre[fa]=fb;
                if(Find(x)==Find(y)) break;
            }
            if((i==1)&&(Find(x)!=Find(y)))
            {
                printf("IMPOSSIBLE
    ");
                flag=1;
                break;
            }
            if(Find(x)!=Find(y)) break;
            if(a1*a[i].w>=a2*a[j].w) a1=a[j].w,a2=a[i].w;
        }
        if(!flag)
        {
            int tmp=__gcd(a1,a2);
            if(tmp==a2) printf("%d
    ",a1/a2);
            else printf("%d/%d
    ",a1/tmp,a2/tmp);
        }
        return 0;
    }
  • 相关阅读:
    关于故事和段子
    SQLserver2008数据库备份和还原问题(还原是必须有完整备份)
    百度文库破解方法
    如何识别病毒,转自百度文库,千辛万苦破解出来的
    20个人艰不拆的事实:知道真相的我眼泪掉下来 T.T
    linux学习网站分享
    个人对于腾讯和优酷的看法
    今天去客户现场的一些感想
    基于 Blazui 的 Blazor 后台管理模板 Blazui.Admin 正式尝鲜
    新手福利!Blazor 从入门到砖家系列教程(你真的可以成为砖家)
  • 原文地址:https://www.cnblogs.com/d-e-v-i-l/p/5857112.html
Copyright © 2020-2023  润新知