首页 > 其他分享 >并查集-讲课内容补全(未完

并查集-讲课内容补全(未完

时间:2023-07-27 11:45:20浏览次数:45  
标签:const 补全 int fy 讲课 查集 find fx ll

施工中......

先在这里给出我的并查集模板

以下为比较常用的

路径压缩

int f[MAXN],n,m;
void clean() {
    for(int i=1; i<=n; i++) f[i]=i;
}
int find(int x) {
    if(x!=f[x]) f[x]=find(f[x]);
    return f[x];
}
void add(int x,int y) {
    int fx=find(x),fy=find(y);
    if(fx!=fy) f[fx]=fy;
}

带权

int find(int x) {
    if(x==f[x]) return x;
    else {
        int t=f[x];
        f[x]=find(f[x]);
        d[x]+=d[t];
        return f[x];
    }
}
void add(int x,int y,int v) {
    int fx=find(x),fy=find(y);
    if(fx!=fy) {
        f[fx]=fy;
        d[fx]=-d[x]+d[y]+v;
    }
}

课后题目

A 宝可梦对决

HZNUOJ--宝可梦决战

思路:套用带权并查集 把权值%3  最后判断克制关系

实现代码(写的比较早 仅供参考)

#include<iostream>
#include<stdio.h>
using namespace std;
int f[100000],d[100000];
int find(int x){
    if(x!=f[x])
    {
        int t=f[x];
        f[x]=find(f[x]);
        d[x]=(d[x]+d[t])%3;
    }
    
    return f[x];
}
void add(int x,int y){
    int fx=find(x),fy=find(y);
    if(fx!=fy){
        f[fx]=fy;
        d[fx]=(d[y]-d[x]+1)%3;
    }
}
int main(){
    int n,t,i,x,y;
    scanf("%d %d",&n,&t);
    for(i=1;i<=n;i++)
    f[i]=i;
    while(t--){ 
        scanf("%d %d",&x,&y);
        add(x,y);
    }
    scanf("%d %d",&x,&y);
     find(x);find(y);
    //for(i=1;i<=n;i++)
    //cout<<d[i]<<endl;

   
    if(d[x]-d[y]==1||d[x]-d[y]==-2)
    cout<<"wait for me, my dear!"<<endl;
    else if(d[x]==d[y])
    cout<<"can I win the game?"<<endl;    
    else
        cout<<"change! change! change!"<<endl;    
    
}
View Code

B 合根植物

思路:用并查集合起来,然后算根的个数就行了

#include<bits/stdc++.h>
#define close std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
typedef long long ll;
const ll MAXN =  2e6+7;
const ll mod = 1e9+7;
const ll inf = 0x3f3f3f3f;
int f[MAXN],n,m;
void clean() {
    for(int i=1; i<=(n*m); i++) f[i]=i;
}
int find(int x) {
    if(x!=f[x]) f[x]=find(f[x]);
    return f[x];
}
void add(int x,int y) {
    int fx=find(x),fy=find(y);
    if(fx!=fy) f[fx]=fy;
}
void solve(){
    cin>>n>>m;
    clean();
    int q;cin>>q;
    while(q--){
        int u,v;cin>>u>>v;
        add(u,v);
    }
    int ans=0;
    for(int i=1;i<=n*m;i++){
        if(find(i)==i) ans++;
    }
    cout<<ans;
}
signed main(){
    solve();
}
View Code

C 修复公路

建议学完最小生成树再来

思路:每次选最快的合并,合并到不能合并,然后输出最后一个合并的时间

#include<bits/stdc++.h>
#define close std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
typedef long long ll;
const ll MAXN =  3e5+7;
const ll mod = 1e9+7;
const ll inf = 0x3f3f3f3f;
int f[MAXN],n,m;
struct node{
    int u,v,w;
}N[MAXN];
bool bj(node a,node b){
    return a.w<b.w;
}
void clean() {
    for(int i=1; i<=n; i++) f[i]=i;
}
int find(int x) {
    if(x!=f[x]) f[x]=find(f[x]);
    return f[x];
}
void add(int x,int y) {
    int fx=find(x),fy=find(y);
    if(fx!=fy) f[fx]=fy;
}
void solve(){
    cin>>n>>m;
    clean();
    for(int i=1;i<=m;i++){
        cin>>N[i].u>>N[i].v>>N[i].w;
    }
    sort(N+1,N+1+m,bj);
    int ans=0,cnt=0;
    for(int i=1;i<=m;i++){
        int u=N[i].u,v=N[i].v,w=N[i].w;
        if(find(u)!=find(v)){
            add(u,v);
            ans=max(ans,w);
        }
    }
    for(int i=1;i<=n;i++){
        if(find(i)==i) cnt++;
    }
    if(cnt>1) cout<<"-1";
    else cout<<ans;
}
signed main(){
    solve();
}
View Code

 

标签:const,补全,int,fy,讲课,查集,find,fx,ll
From: https://www.cnblogs.com/xishuiw/p/17584555.html

相关文章

  • The Third Letter带权并查集
    Problem-1850H-Codeforces题意是给你a,b,c说明a在b后面c个单位(c<0就是在左边),每个位置只能有一个数,一共有n个位置,告诉你m个关系,问是否符合条件我们可以设置d[x]表示x到它的最早的父节点的距离,然后如果两个数父节点一样,那么c!=d[a]-d[b]时就说明不符合条件那么对于并查......
  • 算法刷题笔记--并查集的运用
    1、题目描述:一个城市中有两个犯罪团伙A和B,你需要帮助警察判断任意两起案件是否是同一个犯罪团伙所为,警察所获得的信息是有限的。假设现在有N起案件(N<=100000),编号为1到N,每起案件由团伙A或团伙B所为。你将按时间顺序获得M条信息(M<=100000),这些信息分为两类:D[a][b]其中[a]和[b]表示两......
  • 算法学习--并查集相关知识及例题
    一、并查集的定义二、基本操作1、初始化一开始,每个元素都是独立的集合#include<iostream>usingnamespacestd;constintmaxN=1000;intfather[maxN];intmain(){for(inti=1;i<=maxN;i++){father[i]=i;}return0;}2、查找递推版本://返......
  • 【学习笔记】并查集
    先来看百度百科上的定义:并查集,在一些有N个元素的集合应用问题中,我们通常是在开始时让每个元素构成一个单元素的集合,然后按一定顺序将属于同一组的元素所在的集合合并,其间要反复查找一个元素在哪个集合中。并查集是一种树型的数据结构,用于处理一些不相交集合(disjointsets)的合......
  • 并查集
    在一些有N个元素的集合应用问题中,我们通常是在开始时让每个元素构成一个单元素的集合,然后按一定顺序将属于同一组的元素所在的集合合并,其间要反复查找一个元素在哪个集合中。这一类问题近几年来反复出现在信息学的国际国内竞赛题中,其特点是看似并不复杂,但数据量极大,若用正常的数据......
  • android studio打印日志过长显示补全
    AndroidStudio打印日志过长显示补全实现步骤作为一名经验丰富的开发者,我将向你介绍如何在AndroidStudio中实现打印日志过长时的显示补全功能。这个功能可以帮助你更方便地查看和调试长日志信息。实现步骤下面是整个实现过程的步骤概览。我们将逐步进行操作,确保你能够完全了解......
  • 擒贼先擒王(并查集)
    擒贼先擒王(并查集)目录擒贼先擒王(并查集)题面题目概括思路AC代码和注释题面快过年了,犯罪分子也开始为年终奖奋斗了。晓哼的家乡出现了多次抢劫事件。由于强盗人数过于庞大,作案频繁,警方想查清楚到底有几个犯罪团伙实在太不容易了,不过警察叔叔还是搜集到了一些线索,需要咱们帮忙分析......
  • 并查集知识梳理
    并查集目录并查集并查集的定义并查集的思想朴素并查集的代码(1)初始化(2)查找(3)合并路径压缩(1)查找代码(2)路径压缩完整代码按秩合并思想实现(1)初始化(2)合并并查集的定义并查集是一种树型的数据结构,用于处理一些不相交集合的合并及查询问题。并查集通常包含两种操作:查找(Find):查询两个......
  • 并查集知识点梳理
    并查集目录并查集并查集的定义并查集的思想朴素并查集的代码(1)初始化(2)查找(3)合并路径压缩(1)查找代码(2)路径压缩完整代码按秩合并思想实现(1)初始化(2)合并并查集的定义并查集是一种树型的数据结构,用于处理一些不相交集合的合并及查询问题。并查集通常包含两种操作:查找(Find):查询两个......
  • java 检查集合长度
    Java检查集合长度的实现方法概述在Java开发中,我们经常需要检查集合的长度,以便判断集合中是否包含足够的元素或者进行其他操作。本文将介绍一个简单的方法来实现Java检查集合长度的功能。实现步骤下面是实现Java检查集合长度的步骤,可以用表格形式展示:步骤描述......