博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
poj 1655 Balancing Act(求树的重心)
阅读量:3607 次
发布时间:2019-05-21

本文共 1257 字,大约阅读时间需要 4 分钟。

 

分类: 
 
106人阅读 
(0) 
 

在一棵树中,去掉一个点,使得剩下的每一颗树的结点数最多的那颗树,结点数最少。

具体解法看注释.

[html] 
  1. /*  
  2.     定义dp[i]为去掉i结点,剩下的树里,结点最多的那颗树的结点数。  
  3.     可分为2类情况。  
  4.     1、由于i结点的儿子结点都成了一棵树的根节点,所以dp[i] = (i的每个儿子所拥有的结点数,的最大值)。  
  5.     2、而另一种情况就是剩下的那棵树,所以dp[i] = N-num[i]。  
  6.     其中num[i]表示以i为根的树的所有结点数,可以dfs求出。  
  7. */  
  8. #include<cstdio>  
  9. #include<algorithm>  
  10. #include<cstring>  
  11. #include<vector>  
  12. using namespace std;  
  13. #define MAXN 20005  
  14. int N;  
  15. vector<int> node[20005];  
  16. int num[MAXN];  
  17. int dp[MAXN];  
  18. bool vis[MAXN]; //由于为无向图,所以用这个来标记此结点是否计算过。  
  19.   
  20. int dfs(int id)  
  21. {  
  22.     int n=node[id].size();  
  23.     vis[id]=1;  
  24.     num[id]=1;  
  25.     for(int i=0;i<n;i++)  
  26.     {  
  27.         if(!vis[node[id][i]])  
  28.         num[id]+=dfs(node[id][i]);  
  29.     }  
  30.     return num[id];  
  31. }  
  32. void cal(int id)  
  33. {  
  34.     int n=node[id].size();  
  35.     int k;  
  36.     vis[id]=1;  
  37.     for(int i=0;i<n;i++)  
  38.     {  
  39.         k=node[id][i];  
  40.         if(vis[k])    //只有可能是它老爸  
  41.         {  
  42.             dp[id]=max(dp[id],N-num[id]);  
  43.         }  
  44.         else          //它儿子  
  45.         {  
  46.             dp[id]=max(dp[id],num[k]);  
  47.             cal(k);  
  48.         }  
  49.     }  
  50. }  
  51. int main()  
  52. {  
  53.     int t,a,b;  
  54.     scanf("%d",&t);  
  55.     while(t--)  
  56.     {  
  57.         scanf("%d",&N);  
  58.         for(int i=1;i<=N;i++)  
  59.             node[i].clear();  
  60.         memset(dp,0,sizeof(dp));  
  61.         for(int i=1;i<N;i++)  
  62.         {  
  63.             scanf("%d%d",&a,&b);  
  64.             node[a].push_back(b);  
  65.             node[b].push_back(a);  
  66.         }  
  67.         memset(vis,0,sizeof(vis));  
  68.         dfs(1);  
  69.         memset(vis,0,sizeof(vis));  
  70.         cal(1);  
  71.         int ans=0x7fffffff;  
  72.         int k;  
  73.         for(int i=1;i<=N;i++)  
  74.         {  
  75.             if(dp[i]<ans)  
  76.             {  
  77.                 ans=dp[i];  
  78.                 k=i;  
  79.             }  
  80.         }  
  81.         printf("%d %d\n",k,ans);  
  82.     }  
  83.     return 0;  
  84. }  

转载地址:http://nftzn.baihongyu.com/

你可能感兴趣的文章
非计算机专业本科毕业如何迅速成长为一名算法工程师
查看>>
关于自然语言处理(NLP)的个人学习资料
查看>>
BERT
查看>>
Java keytool生成jks证书,并使用openssl查看公钥信息
查看>>
mysql创建存储过程,set动态赋值
查看>>
【c语言】蓝桥杯算法提高 Quadratic Equation
查看>>
【c语言】蓝桥杯算法提高 输入输出格式练习
查看>>
【c语言】蓝桥杯算法提高 勾股数
查看>>
【c语言】蓝桥杯算法提高 c++_ch02_04
查看>>
【c语言】蓝桥杯算法提高 3-1课后习题2
查看>>
【c语言】蓝桥杯算法提高 3-2求存款
查看>>
【c语言】蓝桥杯算法提高 3-3求圆面积表面积体积
查看>>
【c语言】蓝桥杯算法提高 P0401
查看>>
【c语言】蓝桥杯算法提高 P0402
查看>>
【c语言】蓝桥杯算法提高 三个整数的排序
查看>>
【c语言】蓝桥杯算法提高 P0101
查看>>
【c语言】统计字符次数
查看>>
CTDB原理介绍
查看>>
CTDB配置文件参数解析
查看>>
利用NFS共享搭建CTDB集群
查看>>