题目大意:中文题。
算法思路:因为改变一个节点的颜色,只会影响到这个节点的父节点和子节点,所以,我们只需要在一开始建立好节点之间的关系maps[i][j](maps[i][j]表示第i个节点的子节点里颜色为j的节点个数),之后再没改变一个节点的颜色,就对该节点的父节点和和子节点进行操作即可。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<map>
using namespace std;
#define MAXN 100050
int t,n,m,d,q;
vector<int>v[MAXN];
int col[MAXN];
int par[MAXN];
map<int,int>maps[MAXN];
int main()
{
scanf("%d",&t);
int sym=1;
while(t--)
{
memset(col,0,sizeof(col));
scanf("%d",&n);
int l,r;
for(int i=1; i<=n; i++)
{
par[i]=i;
v[i].clear();
maps[i].clear();
}
for(int i=1; i<=n-1; i++)
{
scanf("%d%d",&l,&r);
v[l].push_back(r);
v[r].push_back(l);
}
for(int i=1; i<=n; i++)
{
for(int j=0; j<v[i].size(); j++)
{
if(v[i][j]==par[i])
continue;
maps[i][0]++;
par[v[i][j]]=i;
}
}
scanf("%d",&q);
int flag,ans=1,x,y;
printf("Case #%d:\n",sym++);
while(q--)
{
scanf("%d",&flag);
if(flag==1)
printf("%d\n",ans);
else
{
scanf("%d%d",&x,&y);
if(col[x]==y)
continue;
//对子节点
ans-=maps[x][y];
ans+=maps[x][col[x]];
//对父节点
if(par[x]!=x)
{
if(y==col[par[x]])
ans--;
if(col[x]==col[par[x]])
ans++;
maps[par[x]][y]++;
maps[par[x]][col[x]]--;
}
col[x]=y;
}
}
}
return 0;
}