银河英雄传说
题意:给你n个战舰,第i个战舰初始都在第i列上,现在有两种操作:M i j,把i列的战舰按原有顺序依次接到j列尾端,C i j,查询i与j号战舰之间隔几个战舰,
如果未在一列输出-1。
思路:把并查集稍微改一下就行了,用一个数组记录隔几个,还用一个数组记录每一列的当前容量。
#include<cstring> #include<algorithm> #include<vector> #include<map> #include<queue> #include<cstdio> #include<cmath> #define ll long long using namespace std; int fa[30010],num[30010],dis[30010]; int get(int x) { if(x!=fa[x]) { int k=fa[x]; fa[x]=get(fa[x]); dis[x]+=dis[k]; num[x]=num[fa[x]]; } return fa[x]; } void merge(int x,int y) { int r1=get(x),r2=get(y); if(r1!=r2) { fa[r1]=r2; dis[r1]=dis[r2]+num[r2]; num[r2]+=num[r1]; num[r1]=num[r2]; } } int query(int x,int y) { int r1=get(x),r2=get(y); if(r1!=r2) return -1; else return abs(dis[x]-dis[y])-1; } int main() { int t; for(int i=1;i<=30008;i++) { fa[i]=i; num[i]=1; } scanf("%d",&t); while(t--) { char c[2]; int x,y; scanf("%s",c); // getchar(); scanf("%d%d",&x,&y); //printf("%c\n",c); if(c[0]=='M') merge(x,y); else { printf("%d\n",query(x,y)); } } }