http://poj.org/problem?id=1962 (题目链接)
时隔多年又一次写带权并查集。
题意
n个节点,若干次询问,I x y表示从x连一条边到y,权值为|x-y|%1000;E x表示询问x到x所指向的终点的距离。
Solution
很裸的带权并查集。
代码
// poj1962 #include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #include<cmath> #include<string> #define LL long long #define MOD 1000 #define inf 2147483640 #define Pi acos(-1.0) #define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout); using namespace std; int getint() { int f=1,x=0;char ch=getchar(); while (ch<='0' || ch>'9') {if (ch=='-') f=-1;ch=getchar();} while (ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();} return x*f; } const int maxn=20010; int r[maxn],fa[maxn],n; int find(int x) { if (x==fa[x]) return x; int f=find(fa[x]); r[x]=r[x]+r[fa[x]]; fa[x]=f; return f; } int main() { int T;scanf("%d",&T); while (T--) { scanf("%d",&n); for (int i=1;i<=n;i++) fa[i]=i,r[i]=0; char ch[10]; while (scanf("%s",ch)!=EOF) { int x,y; if (ch[0]=='O') break; else if (ch[0]=='E') { scanf("%d",&x); find(x); printf("%d ",r[x]); } else { scanf("%d%d",&x,&y); fa[x]=y; r[x]=abs(x-y)%MOD; } } } return 0; }