省赛冲刺 并查集

Posted 钟钟终

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了省赛冲刺 并查集相关的知识,希望对你有一定的参考价值。

#876. pSort

最难的处理点被双重循环解决了,有点大惊失色……

#include <bits/stdc++.h>

using namespace std;
const int inf=0x3f3f3f3f;
const int N=1e2+5;
int n,b[N],d[N],f[N];
int r_find(int r)

    if(f[r]==r)
        return f[r];
    f[r]=r_find(f[r]);
    return f[r];

void update(int x,int y)

    int fx=r_find(x),fy=r_find(y);
    if(fx!=fy)
        f[fx]=fy;

int main()

    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>b[i],f[i]=i;
    for(int i=1;i<=n;i++)
        cin>>d[i];
    for(int i=1;i<=n;i++)
    
        if(i+d[i]<=n)
            update(i,i+d[i]);
        if(i-d[i]>=1)
            update(i-d[i],i);
    

    for(int i=1;i<=n;i++)
    
        int tmp=r_find(i);
        int flag=0;
        for(int j=1;j<=n;j++)
        
            if(r_find(j)==tmp&&b[j]==i)
            
                flag=1;break;
            
        
        if(!flag)
        
            cout<<"NO"<<endl;return 0;
        
    
    cout<<"YES"<<endl;
    return 0;


P1340 兽径管理
注意天数发生的顺序,可在结构体中存储天数,如果每次都sort快排一遍,会很花时间;
合并道路的时候,道路发现的id号必须严格小于当前天数;
此外,当加入的边数等于n-1时,在进行输出等相关操作。

#include <bits/stdc++.h>
#define endl '\\n'
using namespace std;
const int inf=0x3f3f3f3f;
const int N=1e4+5;
int n,w,cnt,num,ans,f[N],mx;
int r_find(int r)

    if(f[r]==r)
        return f[r];
    f[r]=r_find(f[r]);
    return f[r];

struct node

    int u,v,dis,id;
e[N];
void add(int u,int v,int dis)

    e[++cnt].u=u,e[cnt].v=v,e[cnt].dis=dis;

bool cmp(node e1,node e2)

    return e1.dis<e2.dis;

void kruskral(int p)

    ans=0;
    int tmp=0;
    for(int i=1;i<=n;i++) f[i]=i;
    for(int i=1;i<=cnt;i++)
    
        int fx=r_find(e[i].u),fy=r_find(e[i].v);
        if(fx!=fy&&e[i].id<=p)
        
            f[fx]=fy;
            mx=max(mx,e[i].dis);
            ans+=e[i].dis;
            tmp++;
            if(tmp==n-1)
            
                cout<<ans<<endl;return;
            

        
    
    cout<<-1<<endl;

int main()

    cin>>n>>w;
    for(int i=1;i<=w;i++)
    
        int u,v,w;cin>>u>>v>>w;
        add(u,v,w);e[i].id=i;
    
    sort(e+1,e+cnt+1,cmp);
    for(int i=1;i<=w;i++)
        kruskral(i);
    return 0;


https://www.luogu.com.cn/problem/P1892敌人的敌人是朋友,若a和b是敌人,b和c是敌人,则a和c是朋友,a和c属于同一个集合中;我们需要开一个数据记录这个人的敌人是谁,当此人和其他人是敌人时,则需要合并这个人的敌人和其他人;
算一种解决问题的思路。

#include <bits/stdc++.h>

using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=1e4+5;
int p[maxn],f[maxn],n,m;
int r_find(int r)

    if(f[r]==r)
        return r;
    f[r]=r_find(f[r]);
    return f[r];

int main()

    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) f[i]=i;
    for(int i=1;i<=m;i++)
    
        char c;int a,b;
        cin>>c>>a>>b;
        if(c=='F')
        
            int fx=r_find(a),fy=r_find(b);
            f[fx]=fy;
        
        if(c=='E')
        
            if(p[a])
            
                int fx=r_find(p[a]),fy=r_find(b);
                f[fx]=fy;
            
            if(p[b])
            
                int fx=r_find(a),fy=r_find(p[b]);
                f[fx]=fy;
            
            p[a]=b,p[b]=a; //存储敌人
        
    
    int ans=0;
    for(int i=1;i<=n;i++)
    
        if(f[i]==i) ans++;
    
    cout<<ans<<endl;
    return 0;


创作打卡挑战赛 赢取流量/现金/CSDN周边激励大奖

以上是关于省赛冲刺 并查集的主要内容,如果未能解决你的问题,请参考以下文章

洛谷P1525 关押罪犯 并查集

[qbzt寒假] 并查集

并查集团伙

BZOJ 1370: [Baltic2003]Gang团伙(luogu 1892)(种类并查集)

并查集之团伙(codevs)

团伙(并查集经典)