问题描述
输入样例:
1 3
101
1 2
2 3
输出样例:
YES
思路:
这道题还是比较好想的,因为它构造的二叉树是用边连接起来的,不是像之前一样从上到下从左到右按编号构造的,所以可以用邻接表来存每个点还有边,这样可以很方便的找到每个点的相邻点,然后再判断每个点是否有两个相邻点和它颜色一样(即三个连续点同色),这样就可以判断不美观的圣诞树了。
示例代码:
cpp
#include<iostream>
#include<cstring>
using namespace std;
const int N = 1010;
int h[N], e[N], ne[N], idx;
char color[N];
void add(int a, int b)
{
e[idx] = b;
ne[idx] = h[a];
h[a] = idx++;
}
int main()
{
int t;
cin >> t;
while (t--)
{
idx=0; //对于每个样例,都需要重置idx为0,不然上一个样例创建的邻接表就会影响下一个样例
int n;
cin >> n;
memset(h, -1, sizeof(h)); //邻接表初始化
for (int i = 1; i <= n; i++)
{
cin >> color[i];
}
for (int i = 0; i < n - 1; i++)
{
int a, b;
cin >> a >> b;
add(a, b);
add(b, a);
}
//遍历每个点,如果它有两个邻点颜色和它本身都一样就不行
int flag = 0;
for (int i = 1; i <= n; i++) //遍历所有点
{
int res = 0;
for (int j = h[i]; j != -1; j = ne[j]) //找每个点的邻点
{
int k = e[j]; //邻点的编号
if (color[i] == color[k]) res++; //每次找到一个邻点颜色和当前点一样就计数加一
if (res > 1) //有两个邻点和当前点的颜色一样,说明有三个连续点是同色,即不美观
{
flag = 1;
}
}
if (flag) break; //找到了一组连续三个点是同色,就可以退出了
}
if (flag) cout << "NO" << endl;
else cout << "YES" << endl;
}
return 0;
}
注意:
每次进入新样例都要重置idx为0构造新的邻接表,不然会被上一个样例影响!!!
cpp
while (t--)
{
idx=0; //对于每个样例,都需要重置idx为0,不然上一个样例创建的邻接表就会影响下一个样例
int n;
cin >> n;
memset(h, -1, sizeof(h)); //邻接表初始化
}
然后我的几个错误,输入n-1行写成了
cpp
while(n-1)