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 }