zoukankan      html  css  js  c++  java
  • 并查集,合根植物

    合根植物题目来源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;
    }
  • 相关阅读:
    在QT中应用中文
    DDA画直线
    裁剪算法
    VC6与office2007冲突的解决方法
    肾形图案
    OPENGL函数说明
    基数排序
    Qt信号和槽机制
    分形曼德尔波集合图形
    分形朱利亚集合图形1
  • 原文地址:https://www.cnblogs.com/zlhdbk/p/10566615.html
Copyright © 2011-2022 走看看