zoukankan      html  css  js  c++  java
  • 树的最大独立集

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

      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 }
  • 相关阅读:
    JAVA反射机制
    Android插件化
    MFC项目的建立
    [ACM]躲猫猫
    [ACM]某一天的n天后是几年几月几日
    [ACM]括号配对问题
    开发中好用的网站
    TCP与UDP(实时通讯)
    NSSet基本使用
    NSPredicate(正则表达式)
  • 原文地址:https://www.cnblogs.com/a1225234/p/5240233.html
Copyright © 2011-2022 走看看