0
点赞
收藏
分享

微信扫一扫

Weight the Tree CodeForces - 1646D

​​http://codeforces.com/contest/1646/problem/D​​

在“好”点不能相邻的条件下,使“好”点的数量最多,典型树型DP。

在使“好”点的数量最多的条件下,使权重最小(非“好”点权重为1,“好”点权重为邻接点权重之和),也可按树型DP处理。

#include <bits/stdc++.h>
using namespace std;
const int maxn=2e5+10;

struct node
{
int v,tp,next;
};

node edge[2*maxn];
int first[maxn],dp1[maxn][2],dp2[maxn][2],val[maxn];
int n,num,ans1,ans2;

void addedge(int u,int v)
{
edge[num].v=v;
edge[num].tp=-1;
edge[num].next=first[u];
first[u]=num++;
}

void dfsI(int cur,int fa)
{
int i,v;
dp1[cur][1]=1;
dp2[cur][0]=1;
for(i=first[cur];i!=-1;i=edge[i].next){
v=edge[i].v;
if(v!=fa){
dfsI(v,cur);
dp1[cur][1]+=dp1[v][0];
dp2[cur][1]+=dp2[v][0]+1;
if(dp1[v][0]>dp1[v][1]){
dp1[cur][0]+=dp1[v][0];
dp2[cur][0]+=dp2[v][0];
edge[i].tp=0;
}
else if(dp1[v][0]<dp1[v][1]){
dp1[cur][0]+=dp1[v][1];
dp2[cur][0]+=dp2[v][1]+1;
edge[i].tp=1;
}
else if(dp2[v][0]<dp2[v][1]+1){
dp1[cur][0]+=dp1[v][0];
dp2[cur][0]+=dp2[v][0];
edge[i].tp=0;
}
else{
dp1[cur][0]+=dp1[v][1];
dp2[cur][0]+=dp2[v][1]+1;
edge[i].tp=1;
}
}
}
}

void dfsII(int cur,int fa,int tp)
{
int i,v;
if(tp==0){
val[cur]=1;
}
for(i=first[cur];i!=-1;i=edge[i].next){
v=edge[i].v;
if(v!=fa){
if(tp==0){
dfsII(v,cur,edge[i].tp);
}
else{
dfsII(v,cur,0);
}
}
}
}

int main()
{
int i,u,v;
scanf("%d",&n);
memset(first,-1,sizeof(first));
num=0;
for(i=1;i<=n-1;i++){
scanf("%d%d",&u,&v);
addedge(u,v);
addedge(v,u);
}
if(n==2){
printf("2 2\n1 1\n");
}
else{
dfsI(1,0);
if(dp1[1][0]>dp1[1][1]){
ans1=dp1[1][0],ans2=dp2[1][0];
dfsII(1,0,0);
}
else if(dp1[1][0]<dp1[1][1]){
ans1=dp1[1][1],ans2=dp2[1][1];
dfsII(1,0,1);
}
else if(dp2[1][0]<dp2[1][1]){
ans1=dp1[1][0],ans2=dp2[1][0];
dfsII(1,0,0);
}
else{
ans1=dp1[1][1],ans2=dp2[1][1];
dfsII(1,0,1);
}
for(u=1;u<=n;u++){
if(val[u]){
continue;
}
for(i=first[u];i!=-1;i=edge[i].next){
v=edge[i].v;
val[u]+=val[v];
}
}
printf("%d %d\n",ans1,ans2);
for(i=1;i<=n;i++){
printf("%d ",val[i]);
}
printf("\n");
}
return 0;
}


举报

相关推荐

0 条评论