标题效果:鉴于一棵树。除去一个点之后,这棵树将成为一些中国联通的块。之后该点通过寻求取消最低形成块的最大数目。
思维:树DP思维。通过为每个子树尺寸的根节点深搜索确定。之后该节点然后除去,,还有剩下的部分。求一下这些块中数目的最大值。就是去掉这个点时的ans。然后更新总的ans。
这个题事实上就是树的重心。
CODE:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAX 20010 using namespace std; int cases; int points; int head[MAX],total; int next[MAX << 1],aim[MAX << 1]; int p_ans,ans; inline void Initialize(); inline void Add(int x,int y); int DFS(int x,int last); int main() { for(cin >> cases;cases; --cases) { scanf("%d",&points); Initialize(); for(int x,y,i = 1;i < points; ++i) { scanf("%d%d",&x,&y); Add(x,y),Add(y,x); } DFS(1,0); printf("%d %d\n",p_ans,ans); } return 0; } inline void Initialize() { ans = 0x7f7f7f7f,total = 0; memset(head,0,sizeof(head)); } inline void Add(int x,int y) { next[++total] = head[x]; aim[total] = y; head[x] = total; } int DFS(int x,int last) { int max_size = 0,size = 1; for(int i = head[x];i;i = next[i]) { if(aim[i] == last) continue; int temp = DFS(aim[i],x); max_size = max(max_size,temp); size += temp; } max_size = max(max_size,points - size); if(max_size < ans) ans = max_size,p_ans = x; return size; }
版权声明:本文博客原创文章,博客,未经同意,不得转载。
时间: 2024-10-15 02:27:54