假紫題,
主要難度在證實權值數<=3,
但我不會證,有沒有哪位大佬來教一教我,
剩下的就很簡單了,x的每一個權值,由兒子中不等於此權值的轉移過來,取最小值。c++
#include<bits/stdc++.h> using namespace std; const int N=1e4+6; int n,t1,t2,cnt=0,head[N],f[N][4],minx; struct edge{int nxt,to;}e[N<<1]; inline void add(int u,int v){e[++cnt].nxt=head[u],e[cnt].to=v,head[u]=cnt;} inline int read(){ int T=0,F=1; char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-') F=-1; ch=getchar();} while(ch>='0'&&ch<='9') T=(T<<3)+(T<<1)+(ch-48),ch=getchar(); return F*T; } void dfs(int x,int fa){ f[x][1]=1,f[x][2]=2,f[x][3]=3; for(int i=head[x];i;i=e[i].nxt) if(e[i].to!=fa){ dfs(e[i].to,x); for(int j=1;j<=3;++j){ minx=(N<<3); for(int k=1;k<=3;++k) if(j!=k) minx=min(minx,f[e[i].to][k]); f[x][j]+=minx; } } } int main(){ n=read(); for(int i=1;i<n;++i) t1=read(),t2=read(),add(t1,t2),add(t2,t1); dfs(1,0),printf("%d\n",min(min(f[1][1],f[1][2]),f[1][3])); return 0; }