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); }