·一些很可爱的询问和修改,放松地去用并查集解决。
·英文题,述大意:
输入n(5<=n<=20000)表示树有n个节点,并且会EOF结束地读入不超过 20000个操作,一共有两种:
①I v u:表示将v的父亲节点设置为u(在这之前v没有爸爸),边权设置为abs(v-u)%1000。
②E u:表示询问u到当前它所在树的根节点的距离。
·分析:
为了记录当前一系列加边操作后所有的点的位置情况(因为你随时可能回答询问啊),根据这道题的点关系特点[只在乎点和其根节点的信息],我们选择并查集来加以维护。
然后我们只需要在标准的FindFather函数的回溯过程里面加入边权的累积,这样一次函数就可以既完成路径压缩,又维护了沿途所有点各自到根节点的距离(就是边权和)。
然后这么短的题解让我想起了网络上的人们常常使用的一句题解推托之词:“哎呀,其他的搞一搞就出来了”。但是这道题真是这么单纯。OK。
1 #include<stdio.h> 2 #define go(i,a,b) for(int i=a;i<=b;i++) 3 int T,n,fa[20004],d[20004];char c; 4 int A(int a){return a>0?a:-a;} 5 int find(int u) 6 { 7 if(u==fa[u])return u;int Fa=find(fa[u]); 8 d[u]+=d[fa[u]];return fa[u]=Fa; 9 } 10 int main() 11 { 12 scanf("%d",&T);while(T--&&scanf("%d",&n)) 13 { 14 go(u,1,n)d[fa[u]=u]=0;int u,v; 15 while(scanf(" %c",&c),c!='O') 16 { 17 if(c=='I')scanf("%d%d",&v,&u),fa[v]=u,d[v]=A(v-u)%1000; 18 if(c=='E')scanf("%d",&u),fa[u]=find(u),printf("%d ",d[u]); 19 } 20 } 21 return 0; 22 }//Paul_Guderian
明天当孤独袭来时我不会再流一滴泪,
我会用歌声抹去那创痛的灰烬。—————汪峰《明天》