来自FallDream的博客,未经允许,请勿转载,谢谢。
小Q正在设计一种棋类游戏。在小Q设计的游戏中,棋子可以放在棋盘上的格点中。某些格点之间有连线,棋子只能在有连线的格点之间移动。整个棋盘上共有V个格点,编号为0,1,2…,V-1,它们是连通的,也就是说棋子从任意格点出发,总能到达所有的格点。小Q在设计棋盘时,还保证棋子从一个格点移动到另外任一格点的路径是唯一的。小Q现在想知道,当棋子从格点0出发,移动N步最多能经过多少格点。格点可以重复经过多次,但不重复计数。n,v<=100
很明显是sb树形dp啊,但是这数据范围.....
f[0/1][i][j]第i个节点,走了j次,回不回根节点最大答案,很好转移。
我是不会告诉你们我对着这sb题猛wa了几次的
#include<iostream> #include<cstdio> #include<cstring> #define MN 100 using namespace std; int X;char ch; inline int read() { X = 0 , ch = getchar(); while(ch < '0' || ch > '9') ch = getchar(); while(ch >= '0' && ch <= '9')X = X * 10 + ch - '0',ch = getchar(); return X; } int f1[MN+5][MN+5],f2[MN+5][MN+5],cnt=0,n,m,ans=0,head[MN+5]; struct edge{int to,next;}e[MN*2+5]; inline void ins(int f,int t) { e[++cnt]=(edge){t,head[f]};head[f]=cnt; e[++cnt]=(edge){f,head[t]};head[t]=cnt; } void dfs(int x,int fa) { f1[x][0]=f2[x][0]=1; for(int i=head[x];i;i=e[i].next) if(e[i].to!=fa) { dfs(e[i].to,x); for(int j=m;j;j--) for(int k=0;k<j;k++) { if(k<j-1)f1[x][j]=max(f1[x][j],f1[e[i].to][k]+f1[x][j-k-2]), f2[x][j]=max(f2[x][j],f1[e[i].to][k]+f2[x][j-k-2]); f2[x][j]=max(f2[x][j],f2[e[i].to][k]+f1[x][j-k-1]); } } } int main() { n=read();m=read(); for(register int i=1;i<n;i++)ins(read()+1,read()+1); dfs(1,0); for(register int j=0;j<=m;j++) ans=max(ans,f2[1][j]); cout<<ans; return 0; }