树的最大独立集
给定一棵无根树,选出尽可能多的点,使得任何两个节点均不相邻
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 }