kuangbin带你飞:点击进入新世界
本人算是初学者中的初学者,欢迎交流~
并查集的接触过的不多,大概只有普通并查集,带权并查集,种族并查集,传说中的可持续化并查集只是听说过还没有接触,不过种族并查集可以用带权并查集来做,带权的话又常常跟dp联系在一起,普通并查集可以作为其他算法的一项工具。
kuangbin的题型:
A.普通并查集 参考1.2.3.6.9
B.带权并查集 参考4.5.7.8
C.并查集+DP
kuangbin之外:
[并查集模板]:待更
原题链接:传送门
思路:
#include
#include
#define ll long long
#define R register int
#define inf 0x3f3f3f3f
using namespace std;
const int manx=1e3+5;
int a[manx],x[manx],y[manx],vis[manx];
bool map[manx][manx];
int n,d,u,v,l,r;
int find(int f)
{
if(a[f]==f) return f;
return a[f]=find(a[f]);
}
int main()
{
cin>>n>>d;
for(int i=1;i<=n;i++){
scanf("%d%d",&x[i],&y[i]);
a[i]=i;
}
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
if((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j])<=d*d)
map[i][j]=map[j][i]=true;
char c;
while(cin>>c)
{
if(c=='O'){
scanf("%d",&l);
vis[l]=1;
for(int r=1;r<=n;r++)
{
if(r!=l&&map[l][r]&&vis[r])
{
u=find(l),v=find(r);
if(u==v) continue;
a[u]=v;
}
}
}
else if(c=='S'){
scanf("%d%d",&l,&r);
l=find(l),r=find(r);
if(l==r) printf("SUCCESS\n");
else printf("FAIL\n");
}
}
return 0;
}
原题链接:传送门
思路:
#include
#include
#define ll long long
#define R register int
#define inf 0x3f3f3f3f
using namespace std;
const int manx=3e4+5;
int a[manx];
int find(int x)
{
if(a[x]==x) return x;
return a[x]=find(a[x]);
}
int main()
{
int n,m,u,v;
while(cin>>n>>m)
{
if(n==0&&m==0) break;
for(int i=0;i<n;i++) a[i]=i;
while(m--)
{
int q;
cin>>q>>u;
for(int i=1;i<q;i++){
cin>>v;
a[find(u)]=find(v);
u=v;
}
}
int ans=0;
for(int i=0;i<n;i++)
if(find(a[i])==find(0))
ans++;
cout<<ans<<endl;
}
return 0;
}
原题链接:传送门
思路:
#include
#include
using namespace std;
const int manx=1e3+5;
int a[manx];
int n,m;
int find(int x)
{
if(a[x]==x) return x;
else return a[x]=find(a[x]);
}
void show()
{
for(int i=1;i<=n;i++)
a[i]=i;
}
int main()
{
int t;
cin>>t;
while(t--)
{
scanf("%d %d",&n,&m);
int ans=0;
show();
for(int i=1;i<=m;i++)
{
int u,v;
scanf("%d %d",&u,&v);
u=find(u),v=find(v);
if(u!=v) ans++;
a[u]=v;
}
printf("%d\n",n-ans);
}
return 0;
}
原题链接:传送门
思路:
#include
#include
#define ll long long
#define R register int
#define inf 0x3f3f3f3f
using namespace std;
const int manx=3e5+5;
int a[manx],d[manx];
int find(int x)
{
if(a[x]==x) return x;
int fa=find(a[x]);
d[x]=d[x]+d[a[x]];
return a[x]=fa;
}
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
int ans=0;
for(int i=0;i<=n;i++) a[i]=i,d[i]=0;
for(int i=1;i<=m;i++){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
u--;
int x=find(u),y=find(v);
if(x==y&&d[v]-d[u]!=w) ans++;
else {
if(x<y) a[y]=x,d[y]=d[u]+w-d[v];
else a[x]=y,d[x]=d[v]-w-d[u];
}
}
cout<<ans<<endl;
}
return 0;
}
原题链接:传送门
思路:
#include
#include
#define ll long long
#define R register int
#define inf 0x3f3f3f3f
using namespace std;
const int manx=3e5+5;
int a[manx],d[manx];
int find(int x)
{
if(a[x]==x) return x;
int fa=find(a[x]);
d[x]=(d[x]+d[a[x]])%3;
return a[x]=fa;
}
int main()
{
int n,m,ans=0;
scanf("%d%d",&n,&m);
for(int i=0;i<=n;i++) a[i]=i,d[i]=0;
for(int i=1;i<=m;i++)
{
int u,v,w;
scanf("%d%d%d",&w,&u,&v);
w--;
if(u>n||v>n||(w==2&&u==v)) ans++;
else {
int x=find(u),y=find(v);
if(x==y&&(d[v]-d[u]+3)%3!=w) ans++;
else {
a[y]=x;
d[y]=(d[u]+w-d[v]+3)%3;
}
}
}
cout<<ans<<endl;
return 0;
}
原题链接:传送门
思路:
#include
#include
#include
#include
#include
using namespace std;
const int manx=1e4+5;
int a[manx];
struct node{
int w,id;
}d[manx];
bool cmp(node a,node b){
return a.w>b.w;
}
int find(int x)
{
if(a[x]==-1) return x;
else return a[x]=find(a[x]);
}
int main()
{
int n;
while(cin>>n){
for(int i=1;i<=n;i++) cin>>d[i].w>>d[i].id;
memset(a,-1,sizeof(a));
sort(d+1,d+1+n,cmp);
int ans=0;
for(int i=1;i<=n;i++){
int p= find(d[i].id);
if(p>0){
ans+=d[i].w;
a[p]=p-1;
}
}
cout<<ans<<endl;
}
return 0;
}
原题链接:传送门
思路:
#include
#include
#include
#include
#include
using namespace std;
const int manx=1e4+5;
struct node{
int l,r;
char s[10];
}q[manx];
int a[manx],d[manx],f[manx];
int find(int x)
{
if(a[x]==x)return x;
else{
int root=find(a[x]);
d[x]^=d[a[x]];
return a[x]=root;
}
}
int main(){
int n,m,k=0;
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
scanf("%d%d%s",&q[i].l,&q[i].r,&q[i].s);
q[i].l--;
f[++k]=q[i].l,f[++k]=q[i].r;
}
sort(f+1,f+1+k);
k=unique(f+1,f+1+k)-f-1;
for(int i=1;i<=k;i++) a[i]=i,d[i]=0;
int i;
for(i=1;i<=m;i++)
{
int l=lower_bound(f+1,f+1+k,q[i].l)-f;
int r=lower_bound(f+1,f+1+k,q[i].r)-f;
int u=find(l),v=find(r);
int w=0;
if(q[i].s[0]=='o') w=1;
if(u==v&&d[l]^w!=d[r]) break;
else if(u<v) a[u]=v,d[u]=d[l]^d[r]^w;
else if(u>v) a[v]=u,d[v]=d[l]^d[r]^w;
}
cout<<i-1<<endl;
return 0;
}
原题链接:传送门
思路:
#include
#include
#include
#include
using namespace std;
const int manx=2e4+5;
int a[manx],d[manx];
int find(int x)
{
if(a[x]==x) return x;
else {
int fa=find(a[x]);
d[x]^=d[a[x]];
return a[x]=fa;
}
}
int main()
{
int t,T=1;
scanf("%d",&t);
while(t--)
{
int n,m,flag=0;
scanf("%d%d",&n,&m);
for(int i=0;i<=n;i++) a[i]=i,d[i]=0;
for(int i=1;i<=m;i++){
int u,v;
scanf("%d%d",&u,&v);
if(flag) continue;
int fu=find(u),fv=find(v);
if(fu==fv){
if(d[u]==d[v])
flag=1;
}
else a[fv]=fu,d[fv]=d[u]^d[v]^1;
}
cout<<"Scenario #"<<T++<<":"<<endl;
if(flag) puts("Suspicious bugs found!");
else puts("No suspicious bugs found!");
cout<<endl;
}
return 0;
}
原题链接:传送门
思路:
#include
#include
#include
#include
using namespace std;
int main()
{
int n,m;
while(cin>>n>>m)
{
if(n==-1&&m==-1) break;
if(!n&&!m){
puts("Yes");
continue;
}
set<int>q;
q.insert(n),q.insert(m);
int ans=1;
while(cin>>n>>m)
{
if(!n&&!m) break;
ans++;
q.insert(n),q.insert(m);
}
if(ans==q.size()-1) puts("Yes");
else puts("No");
}
return 0;
}