标签:F12 turn ace contain ssis lis tps dfs put
Input
Output
Sample Input
1 7 2 6 1 2 1 4 4 5 3 7 3 1
Sample Output
1 2
题意就是给你一棵无根树,让你找到一个点,去掉这个点之后使得剩下的子树的最大节点数最小;
思路,就是求树的重心,下面先给出树的重心的定义:对于一棵n个节点的无根树,找到一个点使得把树变成一棵以该节点为根的有根树,这时的最大子树的节点数最小。
定义sizes[i]表示i的最大子树的节点数,定义dp[i]为以i为根的最大子树的节点数。然后递归求解。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdio> 4 #include <vector> 5 #include <algorithm> 6 #include <cstring> 7 using namespace std; 8 typedef long long ll; 9 const int maxn=1e6+5; 11 int dp[maxn]; 12 int sizes[maxn]; 13 int ans,n,sum; 14 vector<int> v[maxn];//二维矩阵存图 15 void dfs(int x,int fa) 16 { 17 sizes[x]=1; 18 int maxx=0; 19 for(int i=0;i<v[x].size();i++) 20 { 21 int y=v[x][i]; 22 if(y!=fa) 23 { 24 dfs(y,x); 25 sizes[x]+=sizes[y]; 26 maxx=max(maxx,sizes[y]); 27 } 28 29 } 30 dp[x]=max(maxx,n-sizes[x]); 31 if(sum>dp[x]) 32 { 33 ans=x; 34 sum=dp[x]; 35 } 36 } 37 int main() 38 { 39 int T; 40 scanf("%d",&T); 41 while(T--) 42 { 43 sum=0x3f3f3f3f; 44 scanf("%d",&n); 45 memset(dp,0,sizeof(dp)); 46 memset(sizes,0,sizeof(sizes)); 47 for(int i=1;i<=n;i++)v[i].clear(); 48 for(int i=1;i<n;i++) 49 { 50 int L,K; 51 scanf("%d%d",&L,&K); 52 v[K].push_back(L); 53 v[L].push_back(K); 54 } 55 dfs(1,-1); 56 printf("%d %d\n",ans,dp[ans]); 57 } 58 59 60 return 0; 61 }
标签:F12 turn ace contain ssis lis tps dfs put
原文地址:https://www.cnblogs.com/Cherry93/p/9960049.html