树的最大独立集 《算法竞赛入门经典》P171

树的最大独立集
(PS:树的最大独立集 《算法竞赛入门经典》P171,大学ACM培训时出给低年级队员练手题目)

对于一棵n(1<n<100)个结点的无根树,选出尽量多的结点,使得任何两个结点均不相邻(称为最大独立集),然后输入n-1条边,输出最大独立集的结点个数。(参阅《算法竞赛入门经典》P171)


输入多组测试数据(使用文件输入结束),
对于每组测试数据:
第一行输入一个n,表示共n个结点,接下来n-1行,每行输入两个结点,表示这两点有一条边


对于每组测试数据:
输出占一行,是一个整数,为最大独立集结点的个数


5

1 2

2 3

3 4

4 5

 

11

1 3

1 4

1 5

1 2

2 6

3 7

3 8

4 9

4 10

5 11

 

 

 

3

7



#include<stdio.h>

#include<malloc.h>

#include<string.h>

#include<iostream>

#include<queue>

 

#include  <cstdlib>

#include  <ctime>

 

using namespace std;

int start;

#define maxv 100

#define maxs 30

#define maxgs 100

int n;

int father[maxv];

int dis[maxv];

bool visited[maxv];

int s[maxv][maxs];

int gs[maxv][maxgs];

int dep;

int d[maxv];

 

 

 

typedef struct tree

{

         intedges[maxv][maxv];

         intdegrees[maxv];

}tree;

 

void Init(tree *t)

{

         inti;

         memset(s,0,sizeof(s));

         memset(gs,0,sizeof(gs));

         memset(dis,0,sizeof(dis));

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

         {

                   t->degrees[i]=0;

                   father[i]=-1;

                   visited[i]=false;

         }

}

 

void Insert(tree *t,int u,int v)

{

         t->edges[u][t->degrees[u]]=v;

         t->degrees[u]++;

}

 

void bfs(tree *t)

{

         queue<int>q;

         dep=0;

         intu,v,i,j,k;

         start=t->edges[1][0];

         q.push(start);

         dis[start]=0;

         //printf("start=%d\n",start);///

         while(!q.empty())

         {

                   u=q.front();

                   q.pop();

                   visited[u]=true;

                   for(i=0;i<t->degrees[u];i++)

                   {

                            v=t->edges[u][i];

                            if(visited[v]==false)

                            {

                                     q.push(v);

                                     dis[v]=dis[u]+1;

                                     if(dep<dis[v])

                                               dep=dis[v];

                                     father[v]=u;

 

                                     for(j=0;;j++)///设置孩子

                                     {

                                               if(s[u][j]==0)

                                               {

                                                        s[u][j]=v;

                                                        break;

                                               }

                                     }

                           

                                     if(father[u]!=-1)///设置孙子

                                     {

                                               for(k=0;;)

                                               {

                                                        if(gs[father[u]][k]==0)

                                                        {

                                                                 gs[father[u]][k]=v;

                                                           break;

                                                        }

                                                         else

                                                            k++;

                                               }

                                     }

 

                            }

                   }

 

         }

}

/*

void print(tree *t)

{

         inti,j,k=0;

         printf("dep=%d\n",dep);

         while(1)

         {

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

                   {

                            if(dis[i]==k)

                            {

                                     printf("%d   ",i,dis[i]);

                                     for(j=0;;j++)//显示其孩子

                                     {

                                               if(s[i][j]==0)

                                               {

                                                        printf("\n");

                                                        break;

                                               }

                                               else

                                                        printf("%d",s[i][j]);

                                     }

                                     for(j=0;;j++)//显示其孙子

                                     {

                                               if(gs[i][j]==0)

                                               {

                                                        printf("\n");

                                                        break;

                                               }

                                               else

                                                        printf("%d",gs[i][j]);

                                     }

                            }

                   }

                   printf("\n");

                   k++;

                   if(k>dep)

                            break;

         }

}

*/

 

/*

void print(tree *t,int root)

{

         inti,j,pro[maxv];

         memset(pro,0,sizeof(pro));

         queue<int>q1;

 

         q1.push(root);

         intu,v;

         while(!q1.empty())

         {

                   u=q1.front();

                   q1.pop();

                   for(i=0;;i++)

                   {

                            if(s[u][j]==0)

                            {

                                     printf("\n");

                                     break;

                            }

                            printf("%d",s[u][j]);

                            q1.push(s[u][j]);

                   }

         }

}

 

*/

 

int max(int a,int b)

{

         returna>b?a:b;

}

 

int counts(int i)

{

         intj,ans=0;

         for(j=0;;j++)

         {

                   if(s[i][j]==0)

                            break;

                   ans+=d[s[i][j]];

         }

         returnans;

}

 

int countgs(int i)

{

         intans=0,j;

         for(j=0;;j++)

         {

                   if(gs[i][j]==0)

                            break;

                   ans+=d[gs[i][j]];

         }

         returnans;

}

 

void sove(tree *t)

{

         inti;

         intcen=dep-1;

         intma=0;

         memset(d,0,sizeof(d));

         for(i=0;i<=n;i++)

         {

                   if(dis[i]==dep)

                            d[i]=1;

         }

         while(1)

         {

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

            {

                   if(dis[i]==cen)

                      d[i]=max(1+countgs(i),counts(i));

            }

            cen--;

            if(cen<0)

                      break;

          }

/*     for(i=1;i<=n;i++)

         {

                   //      printf("%d %d\t",i,d[i]);

                   if(d[i]>ma)

                   {

                            ma=d[i];

                            root=i;

                   }

         }*/

         printf("%d\n",d[start]);

         //print(t,root);

}

 

int main()

{

         inti;

         intu,v;

         tree*t;

         t=(tree*)malloc(sizeof(tree));

         //freopen("in.txt","r",stdin);

         //freopen("out.txt","w",stdout);

 

 

 

         while(scanf("%d",&n)!=EOF)

         {

                   Init(t);

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

                   {

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

                            Insert(t,u,v);

                            Insert(t,v,u);

                   }

                   bfs(t);

                   //print(t);

             sove(t);

      //  cout<<clock()<<"  ";

 

         }

         return0;

}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值