zoukankan      html  css  js  c++  java
  • HDU3560 Graph’s Cycle Component 图论基础题

    并查集运用,最后那一步并查集判断个人觉得有点儿小微妙。

    /*
    *State: HDU3560 234MS 1812K 1260 B C++ 
    *题目大意:
    *        给定一个无向图,求无向图的连通分量的数量,还有连通分量是一个环的
    *        数量。
    *解题思路:
    *        各种解法都行,用并查集比较简单。还可以用广搜,还可以用深搜,但是写起来麻烦。
    *        而且广搜跟深搜的时间复杂度是O(v + e),但是并查集的时间复杂度通过有效地修改
    *        可以改至接近线性,采用启发式合并还有路径压缩,还可以到达O(1),优雅至极。
    *题目困惑:
    *        用并查集开始写,应该是很清晰的思路的,结果因为初始化,各种TLE.怎么都没有想到
    *        是因为初始化导致的TLE,白白贡献了4~5个TLE,囧。不过想不通100000的点,我初始化
    *        哪里会TLE啦。以后要多注意下初始化了。多用脑袋跟时间还内存斤斤计较哈。
    */
    View Code
    #include <iostream>
    using namespace std;
    
    const int MAXN = 100005;
    
    typedef struct _node
    {
        int p, rank;
    }N;
    
    N uqSet[MAXN];
    int vst[MAXN], du[MAXN];
    
    void init(int n)
    {
        for(int i = 0; i < n; i++)
        {
            du[i] = vst[i] = 0;
            uqSet[i].p = i;
            uqSet[i].rank = 0;
        }
    }
    
    int findSet(int x)
    {
        int f = x, t;
        while(x != uqSet[x].p)
            x = uqSet[x].p;
        while(f != x)
        {
            t = uqSet[f].p;
            uqSet[f].p = x;
            f = t;
        }
        return x;
    }
    
    void Union(int x, int y)
    {
        x = findSet(x);
        y = findSet(y);
        if(x == y)
            return ;
        if(uqSet[x].rank > uqSet[y].rank)
        {
            uqSet[y].p = x;
        }
        else
        {
            if(uqSet[x].rank == uqSet[y].rank)
                uqSet[y].rank++;
    
            uqSet[x].p = y;
        }
    }
    
    int main(void)
    {
    #ifndef ONLINE_JUDGE
        //freopen("in.txt", "r", stdin);
    #endif
        int n, m;
        while(scanf("%d %d", &n, &m), n || m)
        {
            init(n);
            int u, v;
            for(int i = 0; i < m; i++)
            {
                scanf("%d %d", &u, &v);
                du[u]++, du[v]++;
                Union(u, v);
            }
            int com = 0;
            int reduce = 0;
    
            for(int j = 0; j < n; j++)
            {
                if(findSet(j) == j)
                    com++;
                if(vst[findSet(j)] == 0 && du[j] != 2)
                {    
                    vst[findSet(j)] = 1;
                    reduce++;
                }
            }
            printf("%d %d\n", com, com - reduce);
        }
        return 0;
    }
  • 相关阅读:
    android通过httpClient请求获取JSON数据并且解析
    Http请求之HttpClient + AsyncTask异步请求
    HttpClient使用线程锁synchronized
    经典讨论(四)
    DRP学习进化模型
    ftk学习记录(button一片)
    MySQL检查连接的最大数量和改变的最大连接数
    Android_开发人员经常使用的颜色
    jQuery组织您钞四----jQuery操作DOM
    Codeforces 461B Appleman and Tree(木dp)
  • 原文地址:https://www.cnblogs.com/cchun/p/2641077.html
Copyright © 2011-2022 走看看