题目大意:中文题。
算法思路:因为改变一个节点的颜色,只会影响到这个节点的父节点和子节点,所以,我们只需要在一开始建立好节点之间的关系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; }