hdu 2545 并查集

题目描述:给定一个无向图,判断这个图是否满足任意两点之间有且只有一条通路。

思路:并查集,若a和b之间有一条边且处于不同的集合中,则将a和b所在集合合并;若a和b本就在同一集合中,则a到b一定有不止一条通路。另外还需要判断一下

是否所有的点最后都在一个集合中,即根的数量是否等于1.

注意:0 0的情况应该输出Yes

 1 #include <iostream>

 2 #include <cstring>

 3 #include <cstdio>

 4 using namespace std;

 5 

 6 const int N = 100007;

 7 int f[N];

 8 bool mark[N];

 9 

10 void init()

11 {

12     for ( int i = 1; i < N; i++ )

13     {

14         mark[i] = false;

15         f[i] = i;

16     }

17 }

18 

19 int find_f( int x )

20 {

21     if ( f[x] != x ) f[x] = find_f(f[x]);

22     return f[x];

23 }

24 

25 void union_set( int x, int y )

26 {

27     //f[x] = y居然会栈溢出

28     f[y] = x;

29 }

30 

31 int main ()

32 {

33     int a, b;

34     while ( 1 )

35     {

36         scanf("%d%d", &a, &b);

37         if ( a == -1 && b == -1 ) break;

38         if ( a == 0 && b == 0 ) 

39         {

40             printf("Yes\n");

41             continue;

42         }

43         init();

44         mark[a] = mark[b] = true;

45         union_set( a, b );

46         bool flag = true;

47         while ( 1 )

48         {

49             scanf("%d%d", &a, &b);

50             if ( a == 0 && b == 0 ) break;

51             if ( !flag ) continue;

52             mark[a] = mark[b] = true;

53             a = find_f(a), b = find_f(b);

54             if ( a == b ) flag = false;

55             else union_set( a, b );

56         }

57         if ( !flag )

58         {

59             printf("No\n");

60             continue;

61         }

62         int cnt = 0;

63         for ( int i = 1; i < N; i++ )

64         {

65             if ( mark[i] && f[i] == i ) cnt++;

66         }

67         if ( cnt == 1 ) printf("Yes\n");

68         else printf("No\n");

69     }

70     return 0;

71 }

 

你可能感兴趣的:(HDU)