P1196 [NOI2002]銀河英雄傳說 題解
阿新 • • 發佈:2020-10-26
Link
Solve
帶權並查集,維護一個\(d[i]\)表示和\(fa[i]\)的距離,\(size[i]\)表示這個子樹的大小。
Code
#include<bits/stdc++.h> using namespace std; int T,N,d[30005],size[30005],fa[30005]; inline int read(){ int ret=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-f;ch=getchar();} while(ch<='9'&&ch>='0')ret=ret*10+ch-'0',ch=getchar(); return ret*f; } inline char read_ch(){ char ch; while(ch!='M'&&ch!='C')ch=getchar(); return ch; } int get(int x){ if(x==fa[x])return x; int rt=get(fa[x]); d[x]+=d[fa[x]]; return fa[x]=rt; } void merge(int x,int y){ int fx=get(x),fy=get(y); if(fx==fy)return ; fa[fx]=fy; d[fx]=size[fy]; size[fy]+=size[fx]; } int query(int x,int y){ int fx=get(x),fy=get(y); if(fx!=fy)return -1; return abs(d[x]-d[y])-1; } int main(){ T=read(); for(int i=1;i<=30000;i++)fa[i]=i,size[i]=1; for(int i=1;i<=T;i++){ char ch=read_ch(); int now_x=read(),now_y=read(); if(ch=='M')merge(now_x,now_y); else printf("%d\n",query(now_x,now_y)); } return 0; }
另一種寫法
#include<bits/stdc++.h> using namespace std; int T,N,d[30005],size[30005],fa[30005]; inline int read(){ int ret=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-f;ch=getchar();} while(ch<='9'&&ch>='0')ret=ret*10+ch-'0',ch=getchar(); return ret*f; } inline char read_ch(){ char ch; while(ch!='M'&&ch!='C')ch=getchar(); return ch; } int get(int x){ if(x==fa[x])return x; int k=fa[x]; fa[x]=get(fa[x]); d[x]+=d[k]; size[x]=size[fa[x]]; return fa[x]; } void merge(int x,int y){ int fx=get(x),fy=get(y); if(fx==fy)return ; fa[fx]=fy; d[fx]+=size[fy]; size[fx]+=size[fy]; size[fy]=size[fx]; } int query(int x,int y){ int fx=get(x),fy=get(y); if(fx!=fy)return -1; return abs(d[x]-d[y])-1; } int main(){ freopen("P1196.in","r",stdin); freopen("P1196.out","w",stdout); T=read(); for(int i=1;i<=30000;i++)fa[i]=i,size[i]=1; for(int i=1;i<=T;i++){ char ch=read_ch(); int now_x=read(),now_y=read(); // cin>>ch>>now_x>>now_y; if(ch=='M')merge(now_x,now_y); else printf("%d\n",query(now_x,now_y)); } return 0; }