poj1419_染色_最大独立集_最大团

题意:

经典的图的染色问题,求对于给定的无向图中,给每个结点染两种不同颜色(黑色和白色)的一种且相邻结点的颜色不同,求染成黑色的最多结点数。

分析:

这个题求的图的最大独立集,最大独立集即为黑色节点的个数。

由于原图的最大独立集=补图的最大团。

而这个题是普通图,所以用回溯法来做,时间复杂度O(n*2^n)

代码:

View Code
 1 #include <iostream>

 2 #include <memory.h>

 3 #include <stdio.h>

 4 using namespace std;

 5 

 6 const int maxnum=101;

 7 bool array[maxnum][maxnum];

 8 bool use[maxnum]; //进入团的标号

 9 bool bestx[maxnum];

10 int cn,bestn,p,e;

11 

12 void dfs(int i)

13 {

14     int j;

15     bool flag;

16 

17     if(i>p)

18     {

19         bestn=cn; //cn的值是递增的

20 //        printf("%d\n",bestn);

21 //        for(j=1;j<=p;j++)

22 //            if(use[j])

23 //                printf("%d ",j);

24 //        printf("\n");  在这里输出不一定是最大团

25         for(j=1;j<=p;j++)  //而是应该赋值给另外一个数组,

26             bestx[j]=use[j];

27         return ;

28     }

29 

30     flag=true;

31     for(j=1;j<i;j++)

32         if(use[j]&&!array[j][i])

33         {

34             flag=false;

35             break;

36         }

37     if(flag)

38     {

39         cn++;

40         use[i]=true;

41         dfs(i+1);

42         cn--;

43     }

44     if(cn+p-i>bestn)  //剪枝

45     {

46         use[i]=false;

47         dfs(i+1);

48     }

49 }

50 

51 int main()

52 {

53     int num,i,u,v;

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

55     while(num--)

56     {

57         memset(array,true,sizeof(array));

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

59         memset(bestx,false,sizeof(bestx));

60         scanf("%d%d",&p,&e);

61         for(i=0;i<e;i++)

62         {

63             scanf("%d%d",&u,&v);

64             array[u][v]=false;

65             array[v][u]=false;

66         }

67 

68         cn=bestn=0;

69         dfs(1);

70         printf("%d\n",bestn);

71         for (i=1; i<=p; i++)

72             if(bestx[i])

73                 printf("%d ",i);

74         printf("\n");

75     }

76 

77     return 0;

78 }

79 

80 /*

81 1

82 5 7

83 1 2

84 1 4

85 1 5

86 2 3

87 2 5

88 3 5

89 4 5

90 */

 

 

你可能感兴趣的:(poj)