如下图所示的一棵二叉树的深度、宽度及结点间距离分别为:
其中宽度表示二叉树上同一层最多的结点个数,节点 �,�u,v 之间的距离表示从 �u 到 �v 的最短有向路径上向根节点的边数的两倍加上向叶节点的边数。
给定一颗以 1 号结点为根的二叉树,请求出其深度、宽度和两个指定节点 �,�x,y 之间的距离。
第一行是一个整数,表示树的结点个数 �n。
接下来 �−1n−1 行,每行两个整数 �,�u,v,表示树上存在一条连接 �,�u,v 的边。
最后一行有两个整数 �,�x,y,表示求 �,�x,y 之间的距离。
输入三行,每行一个整数,依次表示二叉树的深度、宽度和 �,�x,y 之间的距离。
输入 #1复制
10 1 2 1 3 2 4 2 5 3 6 3 7 5 8 5 9 6 10 8 6
输出 #1复制
4 4 8
对于全部的测试点,保证 1≤�,�,�,�≤�≤1001≤u,v,x,y≤n≤100,且给出的是一棵树。
题解:
1: 用dfs求深度
2:用一个cnt数组,记录根经过某个距离所能到达的结点数,cnt表示某个距离;根到 i 有相同距离的点,说明在同一层;直接计算根能到达的点,cnt[a[1][i]]++;
3:用二阶矩阵存图,利用floyd求最短距离
代码:
#include
using namespace std;
int n, depth, width;
int a[105][105];
int vis[105];
int cnt[205];
void dfs(int u, int step) {
for (int i = 1; i <= n; ++i) {
if (!vis[i] && a[u][i] != 1000) {
depth = max(depth, step);
vis[i] = 1;
dfs(i, step + 1);
vis[i] = 0;
}
}
}
int main() {
for (int i = 1; i <= 105; ++i) {
for (int j = 1; j <= 105; ++j) {
a[i][j] = 1000;
}
}
memset(vis, 0, sizeof vis);
cin >> n;
int u, v, x, y;
for (int i = 0; i < n - 1; ++i) {
cin >> u >> v;
a[u][v] = 1;
a[v][u] = 2;
}
cin >> x >> y;
dfs(1, 0);
for (int k = 1; k <= n; ++k) {
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n; ++j) {
a[i][j] = min(a[i][j], a[i][k] + a[k][j]);
}
}
}
for (int i = 2; i <= n; ++i) {
cnt[a[1][i]]++;
}
for (int i = 1; i <= 205; ++i) {
width = max(width, cnt[i]);
}
cout << depth << endl;
cout << width << endl;
cout << a[x][y];
return 0;
}
在一大堆秀恩爱的 ** 之中,来不及秀恩爱的苏大学神踏着坚定(?)的步伐走向了 100100 米跑的起点。这时苏大学神发现,百米赛跑的参赛同学实在是太多了,连体育老师也忙不过来。这时体育老师发现了身为体育委员的苏大学神,便来找他帮忙。
可是苏大学神需要热身,不然跑到一半就会抽(筋)、于是他就找到了你。。。如果你帮助体育老师解决了问题,老师就会给你 55 个积分。
假设一共有 �N(2≤�≤2×1042≤N≤2×104)个参赛选手。(尼玛全校学生都没这么多吧)
老师会告诉你这 �N 个选手的名字。
接着会告诉你 �M(1≤�≤1061≤M≤106)句话,即告诉你学生 A 与学生 B 在同一个组里。
如果学生 A 与学生 B 在同一组里,学生 B 与学生 C 也在同一组里,就说明学生 A 与学生 C 在同一组。
然后老师会问你 �K(1≤�≤1061≤K≤106)句话,即学生 X 和学生 Y 是否在同一组里。
若是则输出 Yes.
,否则输出 No.
。
第一行输入 �N 和 �M。
接下来 �N 行输入每一个同学的名字。
再往下 �M 行每行输入两个名字,且保证这两个名字都在上面的 �N 行中出现过,表示这两个参赛选手在同一个组里。
再来输入 �K。
接下来输入 �K 个体育老师的询问。
对于每一个体育老师的询问,输出 Yes.
或 No.
。
输入 #1复制
10 6 Jack Mike ASDA Michel brabrabra HeHe HeHE papapa HeY Obama Jack Obama HeHe HeHE brabrabra HeHe Obama ASDA papapa Obama Obama HeHE 3 Mike Obama HeHE Jack papapa brabrabra
输出 #1复制
No. Yes. Yes.
题解:
1:套入并查集模板。
2:把字符串利用哈希转换成特定的数字
代码:
#include
using namespace std;
string s3,s1,s2;
int n,m,a[200009],k;
int seed=233;
int fa[200009];
int find(int x)
{
if(fa[x]==x) return x;
return fa[x]=find(fa[x]);
}
int has(string s){
unsigned long long hash_=0;
for(int i=0;i>n>>m;
for(int i=1;i<=n;i++)
{
cin>>s3;
fa[has(s3)]=has(s3);
}
for(int i=1;i<=m;i++)
{
cin>>s1>>s2;
fa[find(has(s2))]=find(has(s1));
}
cin>>k;
for(int i=1;i<=k;i++)
{
cin>>s1>>s2;
if(find(has(s1))!=find(has(s2))) cout<<"No."<