HDU-5423 Rikka with Tree。树深搜

来源:互联网 发布:联通电信可用4g网络 编辑:程序博客网 时间:2024/06/07 10:21

Rikka with Tree

 题意:给出树的定义,给出树相似的定义和不同的定义,然后给出一棵树,求是否存在一颗树即和其相似又与其不同。存在输出NO,不存在输出YES。

 思路:以1号节点为根节点,我们观察到一颗树如果不存在这种树即与其相似又与其不同,那么这棵树要么所有节点的深度都不一样,要么有深度一样的并且他们的父节点都一样,后来想想,如果当前节点的父节点有多个儿子,那么当前节点则不能有儿子节点,否则就可以将儿子节点转移到兄弟节点上。思路很正确,比赛的时候用深搜递归写就错了,改成两层循环枚举任意两个节点看是否符合情况然后就过了,,过了。。代码能力还是不行啊,思路都一样,哪里写错了都不知道。

   来看两种写法:

    深搜标记:WA?

void init(){    memset(d,0,sizeof(d));    memset(vis1,0,sizeof(vis1));     memset(vis2,0,sizeof(vis2));     for(int i=0;i<N;i++) g[i].clear();}void dfs(int u,int fa){    d[u]=d[fa]+1;    if(vis1[d[u]])    {        if(vis1[d[u]]!=fa)//度相同根节点不同那么可以互换        {f=1;//         printf("%d %d %d %d\n",u,fa,d[u],vis1[d[u]]);        }    }    else vis1[d[u]]=fa;    int len=g[u].size();    if(len>1) vis2[u]=1;    for(int i=0;i<len;i++)    {        int v=g[u][i];        if(v!=fa)        {//           printf("%d %d %d %d %d\n",v,u,fa,d[u],vis1[d[u]]);             if(u!=fa&&vis2[fa]) f=1;             dfs(v,u);        }    }}int main(){    int n,u,v;    while(~scanf("%d",&n))    {        init();        for(int i=1;i<n;i++)        {            scanf("%d%d",&u,&v);            g[u].push_back(v);            g[v].push_back(u);        }        f=0;        dfs(1,1);        if(f) puts("NO");        else puts("YES");    }    return 0;}

  以上有种样例能debug:

5

1 2

2 3

3 4

3 5

output: NO

Answer : YES

  深搜预处理+枚举,AC!正确思路:父节点一样的情况下不能有儿子节点,否则可以将儿子节点转移至兄弟节点。

void init(){    memset(pre,0,sizeof(pre));    memset(d,0,sizeof(d));    memset(vis1,0,sizeof(vis1));    memset(vis2,0,sizeof(vis2));    for(int i=0; i<N; i++) g[i].clear();}void dfs(int u,int fa){    d[u]=d[fa]+1;    pre[u]=fa;    int len=g[u].size();    for(int i=0; i<len; i++)    {        int v=g[u][i];        if(v!=fa) dfs(v,u);    }}int main(){    int n,u,v;    while(~scanf("%d",&n))    {        init();        for(int i=1; i<n; i++)        {            scanf("%d%d",&u,&v);            g[u].push_back(v);            g[v].push_back(u);        }        f=0;        dfs(1,1);        for(int i=1; i<=n&&!f; i++)            for(int j=1; j<=n&&!f; j++)                if(i!=j&&d[i]==d[j])                {                    if(pre[i]==pre[j])                    {                        int k1=g[i].size();                        int k2=g[i].size();                        if(k1>1||k2>1) f=1;                    }                    else f=1;                }        if(f) puts("NO");        else puts("YES");    }    return 0;}



0 0
原创粉丝点击