HDU 6228 tree 简单思维树dp

一、前言

前两天沈阳重现,经过队友提点,得到3题的成绩,但是看到这题下意识觉得题目错了,最后发现实际上是题目读错了。。。。GG

感觉自己前所未有的愚蠢了。。。。不过题目读对了也是一道思维题,但是很好理解。

二、题意

对于一个无相无环图,要求找出若干边,满足“这些边被至少K个不同的点集在互相联通的时候访问到”。或者说“这些边都包含在K个不同的点集个字组成的联通快里面”。

三、题解

考虑如何表示一个边,以及这条边两边的点的数量?(这是一棵树)
作为一颗树,就有树边概念,因而可以认为“该树包括他自己在内在树的一边”,“其他节点在树边的另一边”

因而,统计下,有多少符合要求的树边就可以了。具体实现见代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 
 4 const long long MAXN=200000+2333;
 5 int child[MAXN];
 6 vector<int>G[MAXN];
 7 long long n,k;
 8 long long ans=0;
 9 
10 void dfs(int now,int last)
11 {
12     int len=G[now].size();
13     for(int i=0;i<len;++i)
14     {
15         int tar=G[now][i];
16         if(tar==last)continue;
17         dfs(tar,now);
18         child[now]+=child[tar];
19     }    child[now]++; 
20     if(child[now]>=k&&n-child[now]>=k)ans++;
21 
22 }
23 
24 void init()
25 {
26 //    memset(child,0,sizeof(child));
27     ans=0;
28     cin>>n>>k;
29     for(int i=0;i<=n;++i)G[i].clear(),child[i]=0;
30     for(int i=1;i<n;++i)
31     {
32         int a,b;
33         cin>>a>>b;
34         G[a].push_back(b);
35         G[b].push_back(a);
36         
37     }
38     dfs(1,0);
39     cout<<ans<<endl;
40     
41 }
42 
43 int main()
44 {
45     cin.sync_with_stdio(false);
46     int ca;cin>>ca;
47     while(ca--)init();
48     
49     
50     return 0;
51 } 

 

posted @ 2017-11-06 20:18  六花的邪王真眼  阅读(613)  评论(0编辑  收藏  举报