首页 > 代码库 > bzoj1050 旅行comf(并查集)

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_pairtemplate<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(并查集)