树的最大独立集

给定一棵无根树,选出尽可能多的点,使得任何两个节点均不相邻

  1 #include <iostream>
  2 #include <vector>
  3 #include <algorithm>
  4 using namespace std;
  5 
  6 /*********************************/
  7 * 可以动态变化的邻接矩阵
  8 * G[i]表示顶点i的邻接点
  9 /*********************************/
 10 
 11 const int MAXN=100;
 12 vector<int> G[MAXN]; //无根树
 13 int l[MAXN]; //结点层次
 14 int p[MAXN]; //根树
 15 int dp[MAXN]; //dp数组
 16 int sumC[MAXN]; //孩子DP和
 17 int sumS[MAXN]; //孙子DP和
 18 int maxL; //最大层次
 19 int n;
 20 
 21 /*********************************/
 22 * 读入无根树,n顶点,n-1边
 23 /*********************************/
 24 
 25 void readTree()
 26 {
 27     int u,v;
 28     cin>>n;
 29     for(int i=0;i<n-1;++i)
 30     {
 31         cin>>u>>v;
 32         G[u].push_back(v);
 33         G[v].push_back(u);
 34     }
 35 }
 36 
 37 /*********************************/
 38 * 以无根树u顶点为根,构造有根树
 39 * 主函数调用dfs(u,-1);
 40 * 测试数据:
 41     8
 42     0 1
 43     1 4
 44     0 2
 45     0 3
 46     1 5
 47     5 6
 48     5 7
 49 /*********************************/
 50 
 51 void dfs(int u,int fa)
 52 {
 53     int d=G[u].size();
 54      l[u]= (fa==-1)? 0: (l[fa]+1);
 55      if(l[u]>maxL)
 56      {
 57          maxL=l[u];
 58      }
 59     for(int i=0;i<d;++i)
 60     {
 61         int v=G[u][i];
 62         if(v!=fa)
 63         {
 64             dfs(v,p[v]=u);
 65         }
 66     }
 67 }
 68 
 69 int rootDp(int u)
 70 {
 71     //构造u根树
 72     p[u]=-1;
 73     maxL=-1;
 74     dfs(u,p[u]);
 75     for(int i=maxL;i>=0;--i)
 76     {
 77         for(int j=0;j<n;++j)
 78         {
 79             if(l[j]==i)
 80             {
 81                 dp[j]=max(sumS[j]+1,sumC[j]);
 82                 if(i-1>=0)
 83                 {
 84                     sumC[p[j]]+=dp[j];
 85                 }
 86                 if(i-2>=0)
 87                 {
 88                     sumS[p[p[j]]]+=dp[j];
 89                 }
 90             }
 91         }
 92     }
 93     return dp[u];
 94 }
 95 
 96 int main()
 97 {
 98     readTree();
 99     int best=-1;
100     //分别以每个顶点为根
101     for(int i=0;i<n;++i)
102     {
103         memset(sumS,0,sizeof(sumS));
104         memset(sumC,0,sizeof(sumC));
105         int tmp;
106         if((tmp=rootDp(i))>best)
107         {
108             best=tmp;
109         }
110     }
111     //打印结果看看
112     cout<<best<<endl;
113     return 0;
114 }

 

posted @ 2016-03-03 21:54  御心飞行  阅读(259)  评论(0编辑  收藏  举报