Luogu P1272 重建道路 DP
阿新 • • 發佈:2019-04-28
。。 font algo efi pri == bsp ostream time
剛才瞅了半天自己當初寫的,終於瞅出來了。。。QWQ
設f[i][j]表示以i為根的子樹,包含j個節點所需砍掉的最小邊數
那麽可知f[u][1]=u的度;
方程:f[u][j]=min(f[u][j],f[u][j-k]+f[v][k]-2);
為何減2? 因為你已經默認了把與自己相連的所有邊都去掉了,於是相當於多去了邊(u,v)兩次,所以要-2
#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #define R register int usingnamespace std; const int Inf=0x3f3f3f3f,N=201; struct edge{ int v,nxt; }e[N<<1]; int n,m,ans=Inf,cnt; int r[N],fir[N],f[N][N]; inline int g() { R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch==‘-‘?-1:fix; do ret=(ret<<3)+(ret<<1)+(ch^48); while(isdigit(ch=getchar())); return ret*fix; } inline void add(int u,int v) {e[++cnt].v=v,e[cnt].nxt=fir[u],fir[u]=cnt;} void dfs(int u,int fa) { f[u][1]=r[u]; for(R i=fir[u],v=e[i].v;i;i=e[i].nxt,v=e[i].v) { if(v!=fa) { dfs(v,u); for(R j=m;j>=1;j--)for(R k=1;k<=j;k++) f[u][j]=min(f[u][j],f[u][j-k]+f[v][k]-2); } } ans=min(f[u][m],ans); } signed main() { n=g(),m=g();memset(f,0x3f,sizeof(f)); for(R i=1;i<n;i++) {R u=g(),v=g(); add(u,v),add(v,u); r[u]++,r[v]++;} dfs(1,0); printf("%d\n",ans); }
2019.04.28
Luogu P1272 重建道路 DP