题目1 : 彩色的树
时间限制:
2000ms
单点时限:
1000ms
内存限制:
256MB
-
2 3 1 2 2 3 3 1 2 2 1 1 5 1 2 2 3 2 4 2 5 4 1 2 2 1 2 3 2 1
样例输出
-
Case #1: 1 3 Case #2: 1
5
-
-
#include<iostream> #include <vector> #include <fstream> using namespace std; const int maxVex = 100010; vector<int> parent[maxVex]; vector<int> child[maxVex]; int color[maxVex]; bool visited[maxVex]; int num;//tree node number //ifstream in("/Users/urey/data/input"); void create() { int x,y; cin>>num; memset(parent,0,sizeof(parent)); memset(child,0,sizeof(child)); memset(color,0,sizeof(color)); for(int i=1; i<=num-1; i++) { cin>>x>>y; child[x].push_back(y);//x's child is y parent[y].push_back(x);//y's parent is x } } void dfs(int i) { visited[i]=true; for(auto j=child[i].begin();j!=child[i].end();j=next(j)) { if(*j<=num && *j>=1 && color[*j]==color[i] ) { if(!visited[*j]) dfs(*j); } } for(auto j=parent[i].begin();j!=parent[i].end();j=next(j)) { if(*j<=num && *j>=1 && color[*j]==color[i] ) { if(!visited[*j]) dfs(*j); } } } int dfsTraverse() { int ans=0; memset(visited,false,sizeof(visited)); for(int i=1; i<=num; i++) { if(!visited[i]) { dfs(i); ans++; } } return ans; } int main() { int T,q,x,y,ops; cin>>T; for(int i=0; i<T; i++) { create(); cin>>q; cout<<"Case #"<<i+1<<":"<<endl; for(int j=0; j<q; j++) { cin>>ops; if(ops == 1) { cout<<dfsTraverse()<<endl; } if(ops == 2) { cin>>x>>y; color[x]=y; } } } return 0; }
-
描述
给定一棵n个节点的树,节点编号为1, 2, …, n。树中有n - 1条边,任意两个节点间恰好有一条路径。这是一棵彩色的树,每个节点恰好可以染一种颜色。初始时,所有节点的颜色都为0。现在需要实现两种操作:
1. 改变节点x的颜色为y;
2. 询问整棵树被划分成了多少棵颜色相同的子树。即每棵子树内的节点颜色都相同,而相邻子树的颜色不同。
输入
第一行一个整数T,表示数据组数,以下是T组数据。
每组数据第一行是n,表示树的节点个数。接下来n - 1行每行两个数i和j,表示节点i和j间有一条边。接下来是一个数q,表示操作数。之后q行,每行表示以下两种操作之一:
1. 若为"1",则询问划分的子树个数。
2. 若为"2 x y",则将节点x的颜色改为y。
输出
每组数据的第一行为"Case #X:",X为测试数据编号,从1开始。
接下来的每一行,对于每一个询问,输出一个整数,为划分成的子树个数。
数据范围
1 ≤ T ≤ 20
0 ≤ y ≤ 100000
小数据
1 ≤ n, q ≤ 5000
大数据
1 ≤ n, q ≤ 100000