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; }