poj2492_bfs_并查集

题意:

给的就是n个虫子 m对虫子发生过关系 然后问有没有虫子是同性恋。

分析:题目等价为,n个点,m条边,能否仅用两种颜色染完所有点,并使每条边的两个点不同色。

bfs,遍历每个顶点,如果相邻顶点染有相同的颜色,说明有同性恋!

代码:

View Code
 1 #include <iostream>

 2 #include <stdio.h>

 3 #include <memory.h>

 4 #include <queue>

 5 using namespace std;

 6 const int maxnum=2001;

 7 bool array[maxnum][maxnum];

 8 bool use[maxnum];

 9 bool color[maxnum];

10 int m,n;

11 bool flag;

12 queue<int> q;

13 

14 void Init()

15 {

16     int i;

17     int a,b;

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

19     memset(array,false,sizeof(array));

20     memset(use,false,sizeof(use));

21     for(i=1;i<=n;i++)

22     {

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

24         array[a][b]=true;

25         array[b][a]=true;

26     }

27     flag=true;

28 

29     while(!q.empty())

30         q.pop();

31 }

32 

33 void bfs(int u)

34 {

35     int v,i;

36     use[u]=true;

37     color[u]=true;

38     q.push(u);

39     while(!q.empty())

40     {

41         v=q.front();

42         q.pop();

43         for(i=1;i<=m;i++)

44             if(i!=v && array[v][i])

45             {

46                 if(!use[i])

47                 {

48                     color[i]=!color[v];

49                     use[i]=true;

50                     q.push(i);

51                 }

52                 else

53                 {

54                     if(color[i]==color[v])

55                     {

56                         flag=false;

57                         return ;

58                     }

59                 }

60             }

61     }

62 }

63 

64 int main()

65 {

66     int num;

67     scanf("%d",&num);

68     int i,k;

69     for(k=1;k<=num;k++)

70     {

71         Init();

72         for(i=1;i<=m;i++)

73             if(!use[i] && flag)

74                 bfs(i);

75 

76         printf("Scenario #%d:\n",k);

77         if(!flag)

78             printf("Suspicious bugs found!\n\n");

79         else

80             printf("No suspicious bugs found!\n\n");

81     }

82     return 0;

83 }

网上有用并查集的,小小的学习了一下。内存比bfs小的多。

并查集思想:

1.用father[i]表示i的根节点,sex[i]表示与它的根节点相比,true表示性别相同,false表示性别不同

2.对于每对a,b。查找father[a]和father[b],不同进行组合,相同进行判断。

3.在a,b的根节点不同的情况下,需要更新sex[father[a]]和sex[fathe[b]]。

首先求出a,b相对于根节点的sex[a]和sex[b].举例

输入1  2后有。father[2]=1,sex[2]=false;

输入2 3 后:首先得出father[2]=1,father[3]=3,不同。

更新father:father[3]=1

更新sex:

因为根节点1和3相对自己是同性,而2相对于1是异性,所以,这样sex[2]^sex[3]=不同两项异或,为1,

所以sex[3]=true;这样3就与1同性。

代码:

View Code
 1 #include <iostream>

 2 #include <stdio.h>

 3 using namespace std;

 4 const int maxnum=2001;

 5 int root[maxnum];

 6 int sex[maxnum];//相对于父节点的性别,true表示是同性,false表示异性

 7 int m,n;

 8 bool flag;

 9 

10 void Init()

11 {

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

13     int i;

14     for(i=1;i<=m;i++)

15     {

16         root[i]=i;

17         sex[i]=true;

18     }

19     flag=true;

20 }

21 

22 int find(int i)

23 {

24     int t=i;

25     bool f=true;

26     while(t!=root[t])

27     {

28         if(!sex[t])  //sex[t]==false;

29             f=!f;

30         t=root[t];

31     }

32     root[i]=t;  //状态压缩

33     sex[i]=f;   //当前节点相对于根节点的性别

34     return root[i];

35 }

36 

37 void function()

38 {

39     int i;

40     int a,b;

41     int ra,rb;

42     for(i=1;i<=n;i++)

43     {

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

45         if(flag)

46         {

47             ra=find(a);

48             rb=find(b);

49             if(ra==rb)

50             {

51                 if(sex[a]==sex[b])   //找到同性恋

52                     flag=false;

53             }

54             else

55             {

56                 root[rb]=ra;   //合并两个集合

57                 sex[rb]=sex[a]^sex[b]; //更新sex[rb]

58             }

59         }

60     }

61 }

62 

63 int main()

64 {

65     int num;

66     int k;

67     scanf("%d",&num);

68     for(k=1;k<=num;k++)

69     {

70         Init();

71         function();

72         printf("Scenario #%d:\n",k);

73         if(!flag)

74             printf("Suspicious bugs found!\n\n");

75         else

76             printf("No suspicious bugs found!\n\n");

77     }

78     return 0;

79 }

 

tjuoj 1706

你可能感兴趣的:(poj)