Gem bzoj-1369 Baltic-2003ios
題目大意:給你一棵樹,讓你往節點上添天然數,使得任意相鄰節點的數不一樣且使得權值最小。spa
註釋:n爲結點個數,$1\le n\le 10^3$。blog
想法:呵呵,學長一直在罵結論題,我一直以爲沒啥.. ...get
知道tm遇見這玩意兒,臥槽?!string
樹上相鄰節點不一樣色,顏色個數最小值至多爲logn。it
最後,附上醜陋的代碼... ...io
#include <iostream> #include <cstring> #include <cstdio> #include <cstdlib> #include <cmath> #include <algorithm> #include <vector> #define ll long long #define inf 1000000000 using namespace std; ll read() { ll x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int n,cnt; int last[10005],f[10005][25]; struct edge { int to,next; }e[20005]; void insert(int u,int v) { e[++cnt].to=v;e[cnt].next=last[u];last[u]=cnt; e[++cnt].to=u;e[cnt].next=last[v];last[v]=cnt; } void dp(int x,int fa) { for(int j=1;j<=20;j++) f[x][j]=j; for(int i=last[x];i;i=e[i].next) if(e[i].to!=fa) dp(e[i].to,x); for(int j=1;j<=20;j++) { for(int i=last[x];i;i=e[i].next) if(e[i].to!=fa) { int mn=inf; for(int k=1;k<=20;k++) if(j!=k)mn=min(mn,f[e[i].to][k]); f[x][j]+=mn; } } } int main() { n=read(); for(int i=1;i<n;i++) { int u=read(),v=read(); insert(u,v); } dp(1,0); int ans=inf; for(int i=1;i<=20;i++) ans=min(ans,f[1][i]); printf("%d\n",ans); return 0; }
小結:多作一些結論題吧... ...ast