这个题真是。。。看了一会之后,发现有一丝丝的熟悉,再仔细看了看,R,这不是那个将军令么。。。然后果断调出来那个题,还真是,而且貌似还是简化版的。。。于是就直接改了改建树和输入输出直接交了。。阿勒,就20分。。真是不给面子,于是就继续简化了代码。。。然后又交,变0分了。发现建树的时候双向边里面放了顺序一样的字母。。再改过来,A了,然而树形DP做法还未可知。。或许蒟蒻我就只能贪心吧。。
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> #define re register using namespace std; struct po { int next; int to; int dis; }; po edge[1000001]; int head[1000001],b[1000001],temp[1000001],dis[1000001],f[1000001]; int T,s,t,n,m,x,w,a,l,num,flag,ans,visit[1000001],k; inline int read() { char ch=' '; int w=1,x=0; while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar(); if(ch=='-')w=-1,ch=getchar(); while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar(); return x*w; } inline void add_edge(int from,int to,int dis) { edge[++num].next=head[from]; edge[num].to=to; edge[num].dis=1; head[from]=num; } inline void dfs(int x,int fa) { temp[++l]=x; for(re int i=head[x];i;i=edge[i].next) if(edge[i].to!=fa) dfs(edge[i].to,x); } int main() { cin>>n; k=1; for(re int i=1;i<=n;i++) { s=read(); s++; m=read(); for(re int j=1;j<=m;j++) { t=read(); t++; add_edge(s,t,1); add_edge(t,s,1); f[t]=s; } } dfs(1,0); for(re int i=n;i>=2;i--) if(!b[temp[i]]&&!b[f[temp[i]]]) b[f[temp[i]]]=1; for(re int i=1;i<=n;i++) if(b[i]) ans++; cout<<ans; }
给出树状DP做法:
#include<iostream> #include<cstdio> #include<cstring> #define re register using namespace std; struct po { int next; int to; int dis; }; po edge[1000001]; int head[1000001],b[1000001],temp[1000001],dis[1000001],f[1501][3]; int T,s,t,n,m,x,w,a,l,num,flag,ans=987654321,visit[1000001],k; inline int read() { char ch=' '; int w=1,x=0; while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar(); if(ch=='-')w=-1,ch=getchar(); while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar(); return x*w; } inline void add_edge(int from,int to,int dis) { edge[++num].next=head[from]; edge[num].to=to; edge[num].dis=1; head[from]=num; } inline void dfs(int x,int fa) { f[x][1]=1;f[x][0]=0; for(re int i=head[x];i;i=edge[i].next) { int u=edge[i].to; if(u!=fa) { dfs(u,x); f[x][1]+=min(f[u][1],f[u][0]); f[x][0]+=f[u][1]; } } } int main() { cin>>n; k=1; for(re int i=1;i<=n;i++) { s=read(); s++; m=read(); for(re int j=1;j<=m;j++) { t=read(); t++; add_edge(s,t,1); add_edge(t,s,1); } } for(re int i=1;i<=n;i++) { memset(f,0,sizeof(f)); dfs(i,i); ans=min(ans,min(f[i][1],f[i][0])); } cout<<ans; }