初学树形dp,看着雨聚聚的PPT上思路搞出来了。。。
题目意思:找到一个割点,树将被割成两个部分,找到最大的连通块。
状态转移方程:F[i]=max(max(tot[k]),n-tot[i]] (k是i的子树)
然后dfs的时候把状态转移方程带进去就好了,注意每一次都得把自己这个点算上。
另外,为了防止对树进行深搜的时候,因为是一个无向图,会来回往复,每一次记录前一个结点的编号,有效防止“走回头路”
#include <bits/stdc++.h>
using namespace std;
vector <int> G[1010];
int dp[1010];
int ansx,ansnum;
int n;
void dfs(int u,int pre)
{
dp[u]=1;
int m=0;
for(int i=0;i<G[u].size();i++)
{
if(G[u][i]==pre) continue;
dfs(G[u][i],u);
dp[u]+=dp[G[u][i]];
m=max(m,dp[G[u][i]]);
}
m=max(m,n-dp[u]);
if(m<ansnum)
{
ansnum=m;
ansx=u;
}
else if(m==ansnum)
{
if(ansx>u) ansx=u;
}
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
for(int i=1;i<=n;i++)
{
G[i].clear();
dp[i]=0;
}
for(int i=1;i<n;i++)
{
int u,v;
scanf("%d%d",&u,&v);
G[u].push_back(v);
G[v].push_back(u);
}
}
ansx=ansnum=0x3f3f3f3f;
dfs(1,0);
printf("%d %d\n",ansx,ansnum);
}


京公网安备 11010502036488号