樹形DP的不錯的題目 枚舉第一個點,以此爲根dfs,然後對於另一個點v不再路徑u-v上的邊 全要調成指向樹葉,路徑上的邊,相當於01序列化爲11....00
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
#define N 3100
int dp[N][2],n,sum;
struct node
{
int f,y;
};
vector<node>vt[N];
void dfs(int x,int fa,int v)
{
if(fa==-1)
{
dp[x][0]=dp[x][1]=0;
}
else
{
dp[x][1]=dp[fa][1]+(!v);
dp[x][0]=min(dp[fa][1],dp[fa][0])+v;
}
for(int i=0;i<vt[x].size();i++)
{
int f=vt[x][i].f;
int y=vt[x][i].y;
if(y==fa)continue;
sum+=(!f);
dfs(y,x,f);
}
return;
}
int main()
{
cin>>n;
for(int i=0;i<n-1;i++)
{
int a,b;
node s;
cin>>a>>b;
a--;
b--;
s.y=b;
s.f=1;
vt[a].push_back(s);
s.y=a;
s.f=0;
vt[b].push_back(s);
}
int ans=50000000;
for(int i=0;i<n;i++)
{
sum=0;
dfs(i,-1,0);
for(int j=0;j<n;j++)
{
int m=min(dp[j][0],dp[j][1]);
ans=min(ans,sum-dp[j][1]+m);
}
}
cout<<ans<<endl;
return 0;
}