并查集,合根植物

合根植物题目来源http://lx.lanqiao.cn/problem.page?gpid=T458

一开始看到这个题的时候我刚学搜索不就,一想不就是个搜索吗,有什么难的,然后直接就开始搜了,然后就很悲惨的。。超时,超时,超时。。。

再后来就知道了这个

并查集

最好先看一下我的另一篇博客再来看这个会看的更明白一点。https://www.cnblogs.com/zlhdbk/p/10566184.html

这个题的解题思路和那个什么江湖门派合并(另一篇并查集)差不多,每个植物看成是一个人,每株合并植物看成是一个门派,一开始一株植物是一个门派,各自是各自的掌门,连根现象就是门派合并的过程,最后看有几株植物,就是看还剩几个门派。

话不多说,直接看代码

#include <iostream>
using namespace std;
int tree[1000010];
struct dir{int x,y;}a[100001];
int m,n,k;
int findroot(int root)//找自己的掌门,并且压缩关系,使其只存在一级关系
{
    int start,t;
    start=root;
    while(root!=tree[root])
        root=tree[root];
    while(start!=root)
    {
        t=tree[start];
        tree[start]=root;
        start=t;
    }
    return root;
}
int main()
{
    int root1,root2,num;
    cin>>m>>n;
    num=m*n;
    for(int i=1;i<=m*n;i++)
        tree[i]=i;
    cin>>k;
    for(int i=1;i<=k;i++)
        cin>>a[i].x>>a[i].y;
    for(int i=1;i<=k;i++)
    {
        root1=findroot(a[i].x);
        root2=findroot(a[i].y);
        if(root1!=root2)
        {
            tree[root1]=root2;
            num--;
        }
    }
    cout<<num;
    return 0;
}

接下来就放我那个超时(因为超时也不知道运行的结果对不对,反正样例过了就是过了对吧hhh,其实还过了一个点,第二个点就TLE了)的代码吧,做个对比吧。(其实是辛苦写出来的不想删)

#include <iostream>
#include<queue>
using namespace std;
int room[1000][1000];
bool code[1000000];
bool v[100001];
struct dir{int x,y;}a[100001];
int m,n,k;
void bfs(int dx,int dy)
{
    dir start;
    queue<dir> q;
    start.x=dx;
    start.y=dy;
    q.push(start);
    while(!q.empty())
    {
        start=q.front();
        q.pop();
        for(int j=1;j<=k;j++)
        {
            if(!v[j])
            {
                if(start.x==a[j].x||start.x==a[j].y||start.y==a[j].x||start.y==a[j].y)
                {
                    v[j]=true;
                    q.push(a[j]);
                    code[a[j].x]=true;
                    code[a[j].y]=true;
                }
            }
        }
    }
}
int main()
{
    cin>>m>>n;
    int num=1,cnt=0;
    for(int i=0;i<m;i++)
        for(int j=0;j<n;j++)
        {
            room[i][j]=num;
            num++;
        }
    cin>>k;
    for(int i=1;i<=k;i++)
        cin>>a[i].x>>a[i].y;
    for(int i=1;i<=k;i++)
    {
        if(!v[i])
        {
            v[i]=true;
            bfs(a[i].x,a[i].y);
            code[a[i].x]=true;
            code[a[i].y]=true;
            cnt++;
        }
    }
    for(int i=1;i<num;i++)
        if(!code[i])
            cnt++;
        cout<<cnt;
    return 0;
}
原文地址:https://www.cnblogs.com/zlhdbk/p/10566615.html