题目:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=12648 and http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=33982
题意:两题都是比较裸的并查集。。。LA3644判断环路,LA3027算点到根节点的距离。
分析:用带路径压缩的并查集查找操作即可。
LA3644代码:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 1e5+6;
int f[maxn];
int Find(int x)
{
if(f[x]==x)
return x;
return f[x]=Find(f[x]);
}
int main()
{
int x,y,i,j,fx,fy,ans;
while(scanf("%d",&x)==1)
{
for(i=0;i<maxn;i++)
f[i]=i;
ans=0;
while(x!=-1)
{
scanf("%d",&y);
fx=Find(x);
fy=Find(y);
if(fx==fy)
ans++;
else
f[fx]=fy;
scanf("%d",&x);
}
printf("%d\n",ans);
}
return 0;
}
LA3027代码:
#include <iostream>
#include <cstdio>
using namespace std;
const int maxn = 2e5+6;
const int mod =1000;
int dis[maxn],f[maxn];
int ABS(int a)
{
if(a<0)
return -a;
return a;
}
struct node
{
int d,pa;
node(int a=0,int b=0)
:d(a),pa(b){}
};
node Find(int x)
{
if(f[x]==x)
return node(0,x);
node temp=Find(f[x]);
f[x]=temp.pa;
dis[x]=dis[x]+temp.d;
return node(dis[x],f[x]);
}
int main()
{
int n,u,d,p,ncase;
char str[10];
scanf("%d",&ncase);
while(ncase--)
{
scanf("%d",&n);
for(int i=0;i<maxn;i++)
{
dis[i]=0;
f[i]=i;
}
while(scanf("%s",str)&&str[0]!='O')
{
if(str[0]=='E')
{
scanf("%d",&u);
Find(u);
printf("%d\n",dis[u]);
}
else
{
scanf("%d%d",&u,&p);
f[u]=p;
dis[u]=ABS(u-p)%mod;
}
}
}
return 0;
}