题意:

输入一棵树,判断这棵树在以节点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. Spring笔记——Spring框架简介和初次框架配置

    Spring简介 Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson 在其著作Expert One-On-One J2EE Deve ...

  2. iOS LLDB调试器和断点调试

    技巧一:运行时修改变量的值 你以前怎么验证是不是某个变量的值导致整段程序不能正常工作?修改代码中的变量的值,然后cmd+r重新启动app?现在你不需要这么做了,只需要设置一个断点,当程序在这进入调试模 ...

  3. hive0.13网络接口安装

    安装好hive 0.13以后,在./lib下找不到hive-hwi-0.13.1.war   ,那该怎么办? 1.下载hive-0.12.0版本,把这一版里面的hive-hwi-0.12.0.war重 ...

  4. installation and configuration of OpenCV4Android SDK

    http://docs.opencv.org/doc/tutorials/introduction/android_binary_package/O4A_SDK.html#running-opencv ...

  5. webapp 开发之iScroll 学习

    demo.html <!doctype html> <html lang="en"> <head> <meta charset=" ...

  6. HDU 4643 GSM 算术几何

    当火车处在换基站的临界点时,它到某两基站的距离相等.因此换基站的位置一定在某两个基站的中垂线上, 我们预处理出任意两基站之间的中垂线,对于每次询问,求询问线段与所有中垂线的交点. 检验这些交点是否满足 ...

  7. 51nod 1050 循环数组最大子段和 (dp)

    http://www.51nod.com/onlineJudge/questionCode.html#problemId=1050&noticeId=13385 参考:http://blog. ...

  8. Restrict each user to a single session in window server 2008 R2 or 2012

    Restrict each user to a single session in window server 2008 R2 or 2012 2014-10-31 In window server ...

  9. c#换ip代理源码

    很多朋友都想如何提高自己的网站流量,可是都没有什么好的办法 经过很长时间的研究,在C#中实现了,当然了,这部分代码其中一部分是网上的,不是原创. using System; using System. ...

  10. 使用@RequestParam绑定请求参数到方法参数

    @RequestParam注解用于在控制器中绑定请求参数到方法参数.用法如下:@RequestMapping public void advancedSearch(   @RequestParam(& ...