题意相当于给你一棵树 让你求每个点的不同子树上的节点个数吧 注意存边的时候存双向边
#include<stdio.h> #include<string.h> #include<iostream> using namespace std; struct node { int to,next; }A[40010]; int tot,list[20010],mark[20010],n; int add(int a,int b) { A[++tot].to = b; A[tot].next = list[a]; list[a] = tot; return 0; } int dp[20010],subtree[20010]; int max(int a,int b) { return a>b?a:b; } int dfs(int point) { mark[point]=1; int b; int k=list[point]; if(k==-1) {dp[point]=n-1;subtree[point]=0;return 0;} for(;k!=-1;k = A[k].next) { b = A[k].to; if(mark[b]) continue; dfs(b); subtree[point]+=subtree[b]+1; dp[point]=max(dp[point],subtree[b]+1); } dp[point]=max(dp[point],n-subtree[point]-1); return 0; } int main() { int i,j,T; scanf("%d",&T); while(T--) { scanf("%d",&n); tot=1; memset(list,-1,sizeof(list)); memset(mark,0,sizeof(mark)); for(i=1;i<n;i++) { int a,b; scanf("%d%d",&a,&b); add(a,b); add(b,a); } memset(dp,0,sizeof(dp)); memset(subtree,0,sizeof(subtree)); memset(mark,0,sizeof(mark)); dfs(1); int Min=3000000,k; for(i=1;i<=n;i++) if(dp[i]<Min) { Min=dp[i]; k=i; } printf("%d %d\n",k,Min); } return 0; }
时间: 2024-10-17 18:10:45