一开始的想法:top判一下环,然后直接D
然后其实整个环一起取是合法的
所以无脑缩点
然而森林转二叉树+treedp真的慢到爆炸,10s跑不出一个点
Rose:我从来都是直接多叉D (%%%%%%
然后就%了一发fyc,然后学会了。(或许某天我又会回来补)
垃圾森林转二叉
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; struct node { int x,y,next; }a[510];int len,last[110]; void eins(int x,int y) { len++; a[len].x=x;a[len].y=y; a[len].next=last[x];last[x]=len; } int z,dfn[110],low[110]; int top,sta[110];bool V[110]; int cnt,belong[110]; void strong_unicom(int x) { dfn[x]=low[x]=++z; sta[++top]=x;V[x]=true; for(int k=last[x];k;k=a[k].next) { int y=a[k].y; if(dfn[y]==0) { strong_unicom(y); low[x]=min(low[x],low[y]); } else { if(V[y]==true) low[x]=min(low[x],dfn[y]); } } if(low[x]==dfn[x]) { int i;cnt++; do { i=sta[top];top--; V[i]=false; belong[i]=cnt; }while(i!=x); } } //---------strong unicom------- struct tree { int lc,rc; }tr[110];int rit[510]; void ins(int x,int y) { if(rit[x]!=0) { int t=rit[x]; rit[x]=y; x=t; tr[x].rc=y; } else tr[x].lc=y, rit[x]=y; } int n; int w[510],v[510],d[510]; int nw[110],nv[110],nd[110]; void composition() { nw[0]=nv[0]=0; for(int i=1;i<=n;i++) { nw[belong[i]]+=w[i]; nv[belong[i]]+=v[i]; if(belong[d[i]]!=belong[i])nd[belong[i]]=belong[d[i]]; } memset(rit,0,sizeof(rit)); for(int i=1;i<=cnt;i++) if(nd[i]==0) ins(cnt+1,i); else ins(nd[i],i); } //-------composition---------- int f[110][510]; void dfs(int x,int m) { if(f[x][m]!=0)return ; if(tr[x].lc==0&&tr[x].rc==0)return ; for(int i=0;i<=m;i++)//分给兄弟 { int sum=0; int d=m-i; if(d>=nw[x]) { sum+=nv[x]; if(tr[x].lc!=0) { dfs(tr[x].lc,d-nw[x]); sum+=f[tr[x].lc][d-nw[x]]; } } if(tr[x].rc!=0) { dfs(tr[x].rc,i); sum+=f[tr[x].rc][i]; } f[x][m]=max(f[x][m],sum); } } //---treeDP-------- int main() { int m; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++)scanf("%d",&w[i]); for(int i=1;i<=n;i++)scanf("%d",&v[i]); len=0;memset(last,0,sizeof(last)); for(int i=1;i<=n;i++) { scanf("%d",&d[i]); eins(d[i],i); } z=top=cnt=0; memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); memset(belong,0,sizeof(belong)); memset(V,false,sizeof(V)); for(int i=1;i<=n;i++) if(dfn[i]==0) strong_unicom(i); composition(); memset(f,0,sizeof(f)); dfs(cnt+1,m); printf("%d ",f[cnt+1][m]); return 0; }
AC:
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; struct node { int x,y,next; }e[510];int elen,elast[110]; void eins(int x,int y) { elen++; e[elen].x=x;e[elen].y=y; e[elen].next=elast[x];elast[x]=elen; } int z,dfn[110],low[110]; int top,sta[110];bool V[110]; int cnt,belong[110]; void strong_unicom(int x) { dfn[x]=low[x]=++z; sta[++top]=x;V[x]=true; for(int k=elast[x];k;k=e[k].next) { int y=e[k].y; if(dfn[y]==0) { strong_unicom(y); low[x]=min(low[x],low[y]); } else { if(V[y]==true) low[x]=min(low[x],dfn[y]); } } if(low[x]==dfn[x]) { int i;cnt++; do { i=sta[top];top--; V[i]=false; belong[i]=cnt; }while(i!=x); } } //---------strong unicom------- node a[510];int len,last[510]; void ins(int x,int y) { len++; a[len].x=x;a[len].y=y; a[len].next=last[x];last[x]=len; } int n; int w[510],v[510],d[510]; int nw[110],nv[110],nd[110]; void composition() { nw[0]=nv[0]=0; for(int i=1;i<=n;i++) { nw[belong[i]]+=w[i]; nv[belong[i]]+=v[i]; if(belong[d[i]]!=belong[i])nd[belong[i]]=belong[d[i]]; } len=0;memset(last,0,sizeof(last)); for(int i=1;i<=cnt;i++) if(nd[i]==0) nd[i]=cnt+1, ins(nd[i],i); else ins(nd[i],i); } //-------composition---------- int m,g[110],f[110][510]; void dfs(int x) { g[x]=g[nd[x]]+nw[x]; for(int i=m;i>=g[x];i--) f[x][i]=max(f[x][i],f[nd[x]][i-nw[x]]+nv[x]); for(int k=last[x];k;k=a[k].next)dfs(a[k].y); int fa=nd[x]; for(int fa=nd[x];fa;fa=nd[fa]) for(int i=0;i<=m;i++)f[fa][i]=max(f[fa][i],f[x][i]); } //---treeDP-------- int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++)scanf("%d",&w[i]); for(int i=1;i<=n;i++)scanf("%d",&v[i]); elen=0;memset(elast,0,sizeof(elast)); for(int i=1;i<=n;i++) { scanf("%d",&d[i]); eins(d[i],i); } z=top=cnt=0; memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); memset(belong,0,sizeof(belong)); memset(V,false,sizeof(V)); for(int i=1;i<=n;i++) if(dfn[i]==0) strong_unicom(i); composition(); memset(f,0,sizeof(f)); dfs(cnt+1); printf("%d ",f[cnt+1][m]); return 0; }