您的位置:首页 > 其它

(vijos 1892 noip 模拟 tree)<树形DP求树的最大匹配及方案数>

2017-08-13 19:24 471 查看
传送门

Solution

以后不补

Code

输入和vijos1892不太一样

// by spli
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<iostream>
#define LL long long
using namespace std;

const int N=1010;
int n;
struct node{
int to,nxt;
}e[N<<1];int head
,cnt;
bool vis
;
LL ff
,gg
;
LL f[2]
;
LL g[2]
;

void add(int f,int t){
cnt++;
e[cnt]=(node){t,head[f]};
head[f]=cnt;
}

void dfs(int u,int fa){
g[0][u]=1;
for(int i=head[u];i!=-1;i=e[i].nxt){
int v=e[i].to;
if(v==fa) continue;
dfs(v,u);
f[0][u]+=ff[v];
g[0][u]*=gg[v];
}
for(int i=head[u];i!=-1;i=e[i].nxt){
int v=e[i].to;
if(v==fa) continue;
LL t=f[0][u]-ff[v]+f[0][v]+1;
LL p=g[0][u]/gg[v]*g[0][v];
if(f[1][u]==t) g[1][u]+=p;
else if(t>f[1][u]){
f[1][u]=t;g[1][u]=p;
}
}
if(f[1][u]>f[0][u]) ff[u]=f[1][u],gg[u]=g[1][u];
else if(f[0][u]>f[1][u]) ff[u]=f[0][u],gg[u]=g[0][u];
else ff[u]=f[1][u],gg[u]=g[0][u]+g[1][u];
}

int main(){
memset(head,-1,sizeof(head));
scanf("%d",&n);
int u,num,x;
for(int i=1;i<=n;++i){
scanf("%d%d",&u,&num);
if(!num) vis[i]=1;
for(int j=1;j<=num;++j){
scanf("%d",&x);
add(u,x);
}
}
dfs(1,1);
if(f[1][1]>f[0][1])
cout<<f[1][1]<<endl<<g[1][1];
else if(f[1][1]==f[0][1]) cout<<f[1][1]<<endl<<g[1][1]+g[0][1];
else cout<<f[0][1]<<endl<<g[0][1];
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: