inline ll find(ll x) { if(fa[x]==x) return x; return find(fa[x]); }
路徑壓縮ios
inline ll find(ll x) { if(fa[x]==x) return x; return fa[x]=find(fa[x]); }
在樸素實現的過程當中,複雜度較高,而路徑壓縮的複雜度爲 \(O(α(n))\) ,可近似認爲其複雜度爲常數級別spa
可是路徑壓縮的作法是把全部的子節點都直接與根節點相連,會破壞樹的原始結構code
對於多種關係的處理,咱們能夠將其合併範圍增大,以表示不一樣的合併關係ci
將 \(1\) ~ \(n\) 範圍表示A類,\(n+1\) ~ \(2n\) 範圍表示B類,\(2n+1\) ~ \(3n\) 範圍表示C類
以後按照題目的食物鏈關係合併便可get
#include<iostream> #include<cstdio> #include<math.h> #include<cstring> #include<algorithm> #define ll long long const ll maxn=5e4+10; ll fa[3*maxn]; ll n,k,a,b,ans; inline ll find(ll x) { if(fa[x]==x) return x; else return fa[x]=find(fa[x]); } int main(void) { scanf("%lld %lld",&n,&k); for(int i=1;i<=n*3;i++) fa[i]=i; for(int i=1;i<=k;i++) { ll op,x,y; scanf("%lld %lld %lld",&op,&x,&y); if(x>n||y>n) { ans++; continue; } if(op==1) { if(find(x+n)==find(y)||find(x+n+n)==find(y)) ans++; else { fa[find(x)]=find(y);//同類 fa[find(x+n)]=find(y+n);//同類 fa[find(x+n+n)]=find(y+n+n);//同類 } } if(op==2) { if(x==y) { ans++; continue; } if(find(x)==find(y)||find(x)==find(y+n+n)) ans++; else { fa[find(x+n)]=find(y+n+n);//B->C fa[find(x)]=find(y+n);//A->B fa[find(x+n+n)]=find(y);//C->A } } } printf("%lld\n",ans); return 0; }
即在路徑壓縮的基礎上,在進行合併以前,先對邊權進行一些處理,以後再進行合併的操做string
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<math.h> #include<vector> #include<queue> #define ll long long using namespace std; const ll maxn=3e4+10; ll t,x,y; char op; ll fa[maxn],dis[maxn],siz[maxn]; inline ll find(ll x) { if(fa[x]==x) return x; ll rot=find(fa[x]); dis[x]+=dis[fa[x]]; return fa[x]=rot; } inline void upd(ll x,ll y) { ll ex=find(x),ey=find(y); fa[ex]=ey; dis[ex]=siz[ey]; siz[ey]+=siz[ex]; } int main(void) { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); for(int i=1;i<=maxn;i++) fa[i]=i,siz[i]=1; memset(dis,0,sizeof(dis)); cin>>t; while(t--) { cin>>op>>x>>y; if(op=='M') { upd(x,y); } if(op=='C') { ll ex=find(x),ey=find(y); if(ex!=ey) { cout<<"-1"<<'\n'; continue; } else { if(x==y) { cout<<"0"<<'\n'; continue; } cout<<abs(dis[x]-dis[y])-1<<'\n'; } } } return 0; }