网上好多都说这是道线段树的题,然而带权并查集的思路更为简单:
题意:每次给出老板与员工的关系,之后给出两个操作:
1.分配任务给某个“老板”,那么他与他旗下子节点都有这个任务。每次员工都会接受新来的任务,放下手中原有任务
2.查询手中的任务
思路:给出relation 数组为任务,time数组为什么时候接受到某个任务
#include <iostream>
#include <stdio.h>
using namespace std;
int father[50010];
int relation[50010];
int time[50010];
void init(int n)
{
for(int i=1;i<=n;i++)
{
relation[i]=-1;
father[i]=i;
time[i]=-1;
}
}
int last;
int find(int x)
{
if(x!=father[x])
{
int tmp=father[x];
find(father[x]); //先确保父亲节点已经维护好
if(time[tmp]>time[x])//如果父亲的任务更晚接到,更新
{
time[x]=time[tmp];
relation[x]=relation[tmp];
}
}
return father[x];
}
void Union(int x,int y)
{
father[x]=y;
}
int main()
{
int T;
cin>>T;
for(int k=1;k<=T;k++)
{ int n,x,y;
cin>>n;
init(n);
for(int j=1;j<n;j++)
{
cin>>x>>y;
Union(x,y);
}
int m;
char ch[5];
cin>>m;
int cot=0;
printf("Case #%d:\n",k);
while(m--)
{ scanf("%s",ch);
if(ch[0]=='T')
{
cin>>x>>y;
time[x]=cot++;
relation[x]=y;
}
else
{ last=-1;
cin>>x;
find(x);
cout<<relation[x]<<endl;
}
}
}
return 0;
}