CSUOJ 1651 Weirdo

1651: Weirdo

Time Limit: 5 Sec  Memory Limit: 128 MB
Submit: 40  Solved: 21
[Submit][Status][Web Board]

Description

小x是一个奇葩,奇葩的小x终于盼来了五一长。。好吧!短假。早已乏味的大学生活让小x感到绝望。与其天天做在电脑面前废寝忘食的打LOL,还不如来一场说走就走的旅行,去看看外面的世界!已经准备去往B市的小x决定让自己的旅行更有意义一点,他觉得人生本就是一场漫长的旅行,重要的不是终点,而是奇葩的路线。他决定找一条通往B市的最均匀的路线!什么样的路线最呀最均匀?当然是这条线路上的路段之间的宽度差的绝对值最小的那条就均匀啦!现在给出n个城市和m条道路及这m条道路的路宽,并且保证居住在A市的小x是可以到达B市,你能帮助小x找出这样的最均匀的路线么,输出这条路线上的最大差值!

Input

每个样例的第一行n,m,A,B分别表示有n个点,m条路段,小x的居住地和小x要到的B市,接下来m行,每行三个数字u,v,w分别表示从u到v的这段路的路宽(路是双向的)。 
2 <= n <= 1500, 
m <= 3000, 
0 <= v,u < n, 
w < INT_MAX

Output

每个样例输出一行

Sample Input

5 5 4 0

0 3 22022

1 2 8871

1 3 9421

2 4 24398

3 4 3344

Sample Output

15527

HINT

 

Source

 

解题:直接枚举下界,求最小上界用类似于最小生成树Kruskal的做法

 

CSUOJ 1651 Weirdo
 1 #include <iostream>

 2 #include <cstdio>

 3 #include <algorithm>

 4 using namespace std;

 5 typedef long long LL;

 6 const int maxn = 40001;

 7 const int INF = 0x3f3f3f3f;

 8 struct arc{

 9     int u,v,w;

10     bool operator<(const arc &t) const{

11         return w < t.w;

12     }

13 }e[maxn];

14 int uf[maxn],n,m,S,T,ret;

15 bool flag;

16 int Find(int x){

17     int t = x;

18     while(uf[x] != x) x = uf[x];

19     while(uf[t] != t){

20         int tmp = uf[t];

21         uf[t] = x;

22         t = tmp;

23     }

24     return x;

25 }

26 int kruskal(int low){

27     for(int i = 0; i <= n; ++i) uf[i] = i;

28     for(int i = low; i < m; ++i){

29         int x = Find(e[i].u);

30         int y = Find(e[i].v);

31         if(x == y) continue;

32         uf[x] = y;

33         if(Find(S) == Find(T)) return e[i].w - e[low].w;

34         if((LL)e[low].w + ret <= e[i].w) return INF;

35     }

36     flag = false;

37     return INF;

38 }

39 int main(){

40     //freopen("Weirdo.in","r",stdin);

41     //freopen("oo.txt","w",stdout);

42     while(~scanf("%d %d %d %d",&n,&m,&S,&T)){

43         for(int i = 0; i < m; ++i)

44             scanf("%d %d %d",&e[i].u,&e[i].v,&e[i].w);

45         sort(e,e+m);

46         ret = INF;

47         flag = true;

48         for(int i = 0; i < m && flag; ++i)

49             ret = min(kruskal(i),ret);

50         printf("%d\n",ret);

51     }

52     return 0;

53 }
View Code

 

你可能感兴趣的:(OJ)