题意:

输入一棵树,判断这棵树在以节点1为根节点时,是否是一棵特殊的树。

相关定义:

1.  定义f[A, i]为树A上节点i到节点1的距离,父节点与子节点之间的距离为1。

2.  对于树A与树B,如果A与B的节点数相同,且无论i为何值,f[A, i]与f[B, i]都相等,则A与B为两棵相似的树。

3.  对于一棵树A,在以节点1为根节点的情况下,如果不存在与其它树与A相似,则A是一棵特殊的树。

输入:

包含多组输入样例。

每组输入样例中首先输入一个整数n,表示一棵含有n个节点的树。

接下来n-1行,每行两个整数a, b表示a与b相连。

输出:

如果这棵树是特殊的树,输出YES,否则输出NO。每组样例占1行。

题解:

如果某个节点x的父节点fx到根节点fg的距离dis[fx]与另一个节点fy的dis[fy]相等,且fx != fy, 那么x在fy上的树与x在fx上的树是相似的。

  首先,我们可以证明,如果树A是一条以节点1为根的单链,那么这棵树是特殊的。

  其次,我们可以证明,如果树A以节点1为根时,除了叶节点的父节点出度为x(x>1)外,其它非子节点的出度都为1。那么这棵树也是特殊的。(当然上一个证明包含在这个证明中)。

  除此之外的所有情况,都是非特殊的。

因此,我们可以先计算出所有节点到根节点(节点1)的距离,然后分析得x2,x3,…xi,…,xn,xi即,到节点1的距离为i的点的数量。根据上面的结论,如果x2到xi的值为1,xi+1的值为m(1<=m<=n-1)则,这棵树是特殊的,否则不是。

计算树上任一点到节点1的距离,可以用dfs很方便得计算出来,但是在比赛的时候,我脑子抽了,居然用了最短路算法……当然,用最短路确实也能解。

其次,在统计结果的时候,我用的方法是将dis[],即节点到根节点的距离按从小到大排序,然后从前往后数,当dis[i] == dis[i+1] && dis[i+1] < dis[i+2]时,则不是特殊树。

看了别人的方法,是统计每种距离的数量的。

但是,我想说的一点是,我在用sort排序时,写的sort(dis+1, dis+n+1, cmp),其中的cmp(int x, int y)中由于直接写了个return x <= y; 所以爆re爆得欲仙欲死,显示非法访问内存了。然后将<=改成<,就过了……

用最短路算法时,3次Dijkstra,tle 1次,900+ms 2次。2次Spfa,都是700ms+。

用dfs,2次是排序的方法,分别是46ms,62ms,1次统计各距离,15ms……看来还是别人家的方法好T_T。

 #include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int NN = ;
const int N = ; int mp[NN][NN];
int dis[NN];
bool vis[NN];
int n; bool cmp(int x, int y)
{
return x <= y; //就死在这个<=上了 = =
} void dij()
{
memset(vis, , sizeof(vis));
dis[] = ;
for(int i = ; i <= n; i++) dis[i] = mp[][i];
vis[] = ;
for(int i = ; i < n; i++)
{
int minn = N, k;
for(int j = ; j <= n; j++)
{
if(!vis[j] && minn > dis[j])
{
minn = dis[j];
k = j;
}
}
if(minn == N) break; vis[k] = ;
for(int j = ; j <= n; j++)
{
if(!vis[j] && dis[j] > dis[k]+mp[j][k]) dis[j] = dis[k]+mp[j][k];
}
}
} int main()
{
//freopen("test.in", "r", stdin);
while(~scanf("%d", &n))
{
for(int i = ; i <= n; i++)
{
for(int j = ; j < i; j++) mp[i][j] = mp[j][i] = N;
mp[i][i] = ;
} for(int i = ; i < n; i++)
{
int a, b;
scanf("%d%d", &a, &b);
mp[a][b] = mp[b][a] = ;
}
dij();
sort(dis+, dis+n+, cmp);
bool flag = ; for(int i = ; i <= n-; i++)
{
if(dis[i] == dis[i+] && dis[i+] < dis[i+]) {flag = ; break;}
}
if(flag) printf("NO\n");
else printf("YES\n");
}
return ;
}

RE code

 #include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
const int NN = ;
const int N = ; int mp[NN][NN];
int dis[NN];
bool vis[NN];
int n; bool cmp(int x, int y)
{
return x < y; //...............
} void dij()
{
dis[] = ;
for(int i = ; i <= n; i++) dis[i] = mp[][i];
vis[] = ;
for(int i = ; i < n; i++)
{
int minn = N, k;
for(int j = ; j <= n; j++)
{
if(!vis[j] && minn > dis[j])
{
minn = dis[j];
k = j;
}
}
if(minn == N) break;
vis[k] = ;
for(int j = ; j <= n; j++)
{
if(!vis[j] && dis[j] > dis[k]+mp[j][k]) dis[j] = dis[k]+mp[j][k];
}
}
} void Spfa()
{
dis[] = ;
for(int i = ; i <= n; i++) dis[i] = N;
vis[] = ;
queue<int>que;
que.push(); int p;
while(!que.empty())
{
p = que.front();
que.pop();
vis[p] = ;
for(int i = ; i <= n; i++)
{
if(dis[i] > dis[p]+mp[i][p])
{
dis[i] = dis[p]+mp[i][p];
if(vis[i] == )
{
que.push(i);
vis[i] = ;
}
}
}
}
} int main()
{
//freopen("test.in", "r", stdin);
while(~scanf("%d", &n))
{
for(int i = ; i <= n; i++)
{
for(int j = ; j < i; j++) mp[i][j] = mp[j][i] = N;
mp[i][i] = ;
vis[i] = ;
} for(int i = ; i < n; i++)
{
int a, b;
scanf("%d%d", &a, &b);
mp[a][b] = mp[b][a] = ;
}
//Spfa();
dij();
sort(dis, dis+n+, cmp);
bool flag = ; for(int i = ; i <= n-; i++)
{
if(dis[i] == dis[i+] && dis[i+] < dis[i+]) {flag = ; break;}
}
if(flag) printf("NO\n");
else printf("YES\n");
}
return ;
}

AC dij+spfa

 #include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std; const int N = ; struct Edge
{
int to, next;
}edge[N]; int dis[N], head[N];
bool vis[N];
int n; bool cmp(int x, int y)
{
return x < y;
} void add(int a, int b, int k)
{
edge[k].to = b;
edge[k].next = head[a];
head[a] = k;
} void init()
{
memset(edge, -, sizeof(edge));
memset(head, -, sizeof(head));
memset(dis, -, sizeof(dis));
for(int i = ; i < n; i++)
{
int a, b;
scanf("%d%d", &a, &b);
add(a, b, i);
}
} void dfs(int x, int k)
{
for(int i = head[x]; i != -; i = edge[i].next)
{
int v = edge[i].to;
if(!vis[v])
{
vis[v] = ;
dis[v] = k;
dfs(v, k+);
vis[v] = ;
}
}
} void outit()
{
/*
sort(dis, dis+n+1, cmp);
bool flag = 0;
for(int i = 2; i <= n-2; i++)
{
if(dis[i] == dis[i+1] && dis[i+1] < dis[i+2]) {flag = 1; break;}
}
if(flag) printf("NO\n");
else printf("YES\n");
*/
int sum[N];
memset(sum, , sizeof(sum));
for(int i = ; i <= n; i++) sum[dis[i]]++;
int ans = ;
for(int i = ; i <= n; i++)
{
if(sum[i] == ) ans++;
else
{
if(sum[i+] == ) ans = n;
break;
}
}
if(ans == n) printf("YES\n");
else printf("NO\n");
} int main()
{
//freopen("test.in", "r", stdin);
while(~scanf("%d", &n))
{
init();
dfs(, );
outit();
}
return ;
}

AC dfs

革命尚未成功,同志仍需努力

hdu 5423 Rikka with Tree(dfs)bestcoder #53 div2 1002的更多相关文章

  1. hdu 5423 Rikka with Tree(dfs)

    Problem Description As we know, Rikka is poor at math. Yuta is worrying about this situation, so he ...

  2. (hdu)5423 Rikka with Tree (dfs)

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5423 Problem Description As we know, Rikka is p ...

  3. HUD5423 Rikka with Tree(DFS)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5423 Rikka with Tree Time Limit: 2000/1000 MS (Java/O ...

  4. HDU 2553 N皇后问题(dfs)

    N皇后问题 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Description 在 ...

  5. 2017ACM暑期多校联合训练 - Team 1 1003 HDU 6035 Colorful Tree (dfs)

    题目链接 Problem Description There is a tree with n nodes, each of which has a type of color represented ...

  6. HDU 5423:Rikka with Tree Dijkstra算法

    Rikka with Tree  Accepts: 207  Submissions: 815  Time Limit: 2000/1000 MS (Java/Others)  Memory Limi ...

  7. HDU 5416 CRB and Tree (技巧)

    题意:给一棵n个节点的树(无向边),有q个询问,每个询问有一个值s,问有多少点对(u,v)的xor和为s? 注意:(u,v)和(v,u)只算一次.而且u=v也是合法的. 思路:任意点对之间的路径肯定经 ...

  8. ACM学习历程—HDU5423 Rikka with Tree(搜索)

    Problem Description As we know, Rikka is poor at math. Yuta is worrying about this situation, so he ...

  9. hdu 1016 Prime Ring Problem(dfs)

    Prime Ring Problem Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

随机推荐

  1. Java Map排序

    Map排序的方式有很多种,这里记录下自己总结的两种比较常用的方式:按键排序(sort by key), 按值排序(sort by value). 1.按键排序 jdk内置的java.util包下的Tr ...

  2. jenkins集成自动化部署插件(一) deploy-plugin

    在实际情况中项目构建成功,特别是web项目构建成功是需要将war放到对应的服务上面,进行运行(测试的阶段可能就是发布到测试服务器上面)这样只需要指定构建的触发策略就可以自动构建以及部署,省去不少人工的 ...

  3. MyBatis学习总结_16_Mybatis使用的几个建议

    1.Mapper层参数为Map,由Service层负责重载. Mapper由于机制的问题,不能重载,参数一般设置成Map,但这样会使参数变得模糊,如果想要使代码变得清晰,可以通过service层来实现 ...

  4. CentOS7安装配置DNS服务器

    准备工作(假设名称为bigcloud.local) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #更改主机名称 #vi /etc/sysconfig/netwo ...

  5. RHEL7-使用Apache服务部署静态网站

    1. 安装Apache服务程序 1.1 在虚拟机中选中光盘镜像,并设置连接 1.2 将光盘设备挂载到/media/cdrom目录 [root@localhost ~]# mkdir -p /media ...

  6. Xlib: connection to ":0.0" refused by server Xlib: No protocol specified解决方案

    Xlib: connection to ":0.0" refused by server Xlib:  No protocol specified 解决办法: 1. 退出oracl ...

  7. LaTeX新人教程,30分钟从完全陌生到基本入门

    by Nan 对于真心渴望迅速上手LaTeX的人,前言部分可以跳过不看. 本教程面向对LaTeX完全无认知无基础的新人.旨在让新人能够用最简单快捷的方式,轻松入门,能够迅速使用LaTeX完成基本的文本 ...

  8. git merge简介【转】

    转自:http://blog.csdn.net/hudashi/article/details/7664382 git merge的基本用法为把一个分支或或某个commit的修改合并现在的分支上.我们 ...

  9. 解决 iReport 生成 pdf 时显示不出中文的问题

    有没有遇到这样的情况:在使用 iReport 做报表时,用pdf预览显示不出中文? 解决步骤是这样的: 1.加入jar包 下载两个jar包:itextasian.jar 和 itext-x.y.jar ...

  10. poj -2229 Sumsets (dp)

    http://poj.org/problem?id=2229 题意很简单就是给你一个数n,然后选2的整数幂之和去组成这个数.问你不同方案数之和是多少? n很大,所以输出后9位即可. dp[i] 表示组 ...