【洛谷P1196】[NOI2002]银河英雄传说
银河英雄传说
并查集时记录下以i为首的队列的长度(如果存在这个队列)num[i],便于合并,
和点i到队首的距离front[i],便于查询(在find时维护)
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 using namespace std; 5 #define N 30010 6 #define abs(x) ((x)>0?(x):-(x)) 7 const int n=30000; 8 int m,fa[N],front[N],num[N]; 9 inline int read(){ 10 int x=0; char c=getchar(); 11 while(c<'0'||c>'9') c=getchar(); 12 while('0'<=c&&c<='9') { x=(x<<3)+(x<<1)+c-'0'; c=getchar(); } 13 return x; 14 } 15 inline int find(int x){ 16 if(fa[x]==x) return x; 17 int fx=find(fa[x]); 18 front[x]+=front[fa[x]]; //改变fa[x]为祖先的同时要把fa[x]到祖先的长度加上 19 return fa[x]=fx; 20 } 21 int main() 22 { 23 for(int i=1;i<=n;i++){ 24 fa[i]=i; 25 front[i]=0; 26 num[i]=1; 27 } 28 scanf("%d",&m); 29 char type[2]; 30 int x,y; 31 while(m--){ 32 scanf("%s",type); 33 x=read(); y=read(); 34 int fx=find(x),fy=find(y); 35 if(type[0]=='M'){ 36 fa[fx]=fy; 37 front[fx]+=num[fy]; //fx前面多了num[fy]个元素 38 num[fy]+=num[fx]; //fy的队列增长了num[fx] 39 num[fx]=0; //fx的队列不存在了 40 } 41 else{ 42 if(fx!=fy) puts("-1"); 43 else 44 printf("%d\n",abs(front[x]-front[y])-1); 45 } 46 } 47 return 0; 48 }