WJMZBMR:ios
这题首先是不能用奇偶层染色的办法来作的,我构造出了至少须要1-3的反例,同时用数学概括法能够证实对于任意n,都有树不能用1-n达到最优解(提示:使用大量叶子节点逼迫某节点染2。。)。。
可是个人构造法弄出来的反例的大小至少是指数增加的,因此我感受对于N<=10000,10种颜色足够了。。更精确的测试代表3种就OK了(!!!!!我能够构造出1000个之内的须要4种颜色的反例啊囧。。这个数据好弱啊。。)。。而后就是简单的树形DP。。。比赛的时候很明显直接DP就能够了。。证实不重要(*^__^*) 嘻嘻……git
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define MAXN 1000008 using namespace std; int n,m,tot,head[MAXN],vet[MAXN],next[MAXN],dp[MAXN][6]; inline int read(){ char ch=getchar(); int f=1,x=0; while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} return x*f; } void add(int x,int y){ tot++; next[tot]=head[x]; head[x]=tot; vet[tot]=y; } void dfs(int u,int fa){ for(int i=head[u];i;i=next[i]){ int y=vet[i]; if(y==fa) continue; dfs(y,u); for(int j=1;j<=5;j++){ int res=2000000000; for(int k=1;k<=5;k++) if(j!=k) res=min(res,dp[y][k]); dp[u][j]+=res; } } for(int i=1;i<=5;i++) dp[u][i]+=i; } int main(){ n=read(); for(int i=1;i<n;i++){ int x,y; x=read(); y=read(); add(x,y); add(y,x); } dfs(1,-1); int ans=2000000000; for(int i=1;i<=5;i++) ans=min(ans,dp[1][i]); printf("%d",ans); }