bzoj1050 旅行comf(并查集)

Posted 恶devil魔

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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\n",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\n");
            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\n",a1/a2);
        else printf("%d/%d\n",a1/tmp,a2/tmp);
    }
    return 0;
}

 

以上是关于bzoj1050 旅行comf(并查集)的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ 1050: [HAOI2006]旅行comf(枚举+并查集)

bzoj 1050 [HAOI2006]旅行comf

1050: [HAOI2006]旅行comf

BZOJ 1050 旅行(并查集)

bzoj1050HAOI2006旅行comf

BZOJ 1050并查集+贪心