HAOI2006(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不可能相同。

Output

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

Sample Input

【样例输入1】
4 2
1 2 1
3 4
2
1 4

【样例输入2】
3 3
1 2 10
1 2 5
2 3 8
1 3

【样例输入3】
3 2
1 2 2
2 3 4
1 3

Sample Output

【样例输出1】
IMPOSSIBLE

【样例输出2】
5/4
【样例输出3】
2

【数据范围】
1< N < = 500
1 < = x, y < = N,0 < v <
30000,x ≠ y
0 < M < =5000

题目分析:T_T...这么水的题我还想了好长时间。。果然还是弱爆了T_T...
我们可以枚举边,每次加边,用并查集维护连通性。。即可。。

?





1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

#include<cstdio>

#include<cstdlib>

#include<algorithm>

const
int N = 510;

const
int M = 5010;

const
int Maxint = 2147483647;

using
namespace std;

#define For(i,n) for(int i=1;i<=n;i++)

#define Rep(i,l,r) for(int i=l;i<=r;i++)

struct
EDGE{

    int
s,t,next,w;

}E[M];

int
head[N],es=1,fa[N];

int
Max,Min = Maxint,n,m,x,y,w,s,t;

double
MIN = Maxint;

void
makelist(int
s,int t,int w){

    E[es].s = s;E[es].t = t;E[es].w = w;

    E[es].next = head[s];

    head[s]=es++;

}

void
init(){

    scanf("%d%d",&n,&m);

    For(i,m){

        scanf("%d%d%d",&x,&y,&w);

        makelist(x,y,w);

    }

    scanf("%d%d",&s,&t);

}

bool
cmp(EDGE A,EDGE B){

    return
A.w<B.w;

}

int
find(int
root){

    if(root!=fa[root]) fa[root] = find(fa[root]);

    return
fa[root];

}

int
gcd(int
a,int b){

    if(!b) return
a;

    else  
return gcd(b,a%b);

}

int
main(){

    init();

    sort(E+1,E+m+1,cmp);

    For(i,m){

        For(j,n) fa[j] = j;

        Rep(j,i,m){

            int
fx = find(E[j].s) , fy = find(E[j].t);

            if(fx!=fy) fa[fx] = fy;

            fx = find(s); fy = find(t);

            if(fx==fy)

                if((double)E[j].w/(double)E[i].w<MIN){

                    MIN = (double)E[j].w / (double)E[i].w;

                    Min = E[i].w;

                    Max = E[j].w;

                    break;

                }

        }

    }

    if(Min==Maxint)  puts("IMPOSSIBLE");

    else{

        int
gcds = gcd(Max,Min);

        if(Max%Min) printf("%d/%d\n",Max/gcds,Min/gcds);

        else       
printf("%d\n",Max/Min);

    }

    return
0;

}

  

时间: 2024-10-09 10:09:07

HAOI2006(BZOJ1050) 旅行comf的相关文章

bzoj1050【HAOI2006】旅行comf

1050: [HAOI2006]旅行comf Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 2205  Solved: 1174 [Submit][Status][Discuss] Description 给你一个无向图,N(N<=500)个顶点, M(M<=5000)条边,每条边有一个权值Vi(Vi<30000).给你两个顶点S和T,求一条路径,使得路径上最大边和最小边的比值最小.如果S和T之间没有路径,输出"IMPOSSI

【BZOJ】【1050】【HAOI2006】旅行comf

枚举/暴力/Kruskal orz……我sb了……其实是sb题<_< 有一道题问的是最小极差生成树……(不记得是什么名字了,就是求最大边权与最小边权差最小的生成树)做法是枚举最小边,然后kruskal找最大边 这题同理,因为$m\leq 5000$,所以$m^2$的算法即可…… 1 /************************************************************** 2 Problem: 1050 3 User: Tunix 4 Language: C

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之间有一条双向 公路,车辆必须以

1050: [HAOI2006]旅行comf

1050: [HAOI2006]旅行comf Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1495  Solved: 737[Submit][Status] Description 给你一个无向图,N(N<=500)个顶点, M(M<=5000)条边,每条边有一个权值Vi(Vi<30000).给你两个顶点S和T,求一条路径,使得路径上最大边和最小边的比值最小.如果S和T之间没有路径,输出”IMPOSSIBLE”,否则输出这个比值,如果需

[HAOI2006]旅行comf

1050: [HAOI2006]旅行comf Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 3450  Solved: 1919 [Submit][Status][Discuss] Description 给你一个无向图,N(N<=500)个顶点, M(M<=5000)条边,每条边有一个权值Vi(Vi<30000).给你两个顶点S和T,求 一条路径,使得路径上最大边和最小边的比值最小.如果S和T之间没有路径,输出"IMPOSS

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

[HAOI2006]旅行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之间有一条

bzoj 1050: [HAOI2006]旅行comf(最小生成树+并查集)

1050: [HAOI2006]旅行comf Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 2405  Solved: 1282 [Submit][Status][Discuss] Description 给你一个无向图,N(N<=500)个顶点, M(M<=5000)条边,每条边有一个权值Vi(Vi<30000).给你两个顶点S和T ,求一条路径,使得路径上最大边和最小边的比值最小.如果S和T之间没有路径,输出"IMPOSS

BZOJ 1050 旅行comf(枚举最小边-并查集)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1050 题意:给出一个带权图.求一条s到t的路径使得这条路径上最大最小边的比值最小? 思路:将边排序.枚举最小边,然后将边一个一个插到并查集里,s和t联通时计算更新答案. struct node { int u,v,w; void get() { RD(u,v,w); } }; int cmp(node a,node b) { return a.w<b.w; } int n,m,s,t;

BZOJ1050 [HAOI2006]旅行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之间有一条双向 公路