• UVALive 6907 Body Building


    题目链接:https://vjudge.net/problem/UVALive-6907

    题意: 给出一张图,判断这张图中有多少个哑铃,哑铃判断的条件是,对于一个连通图:如果找到一条边连接这两个点的个数相同的完全图,那么这个联通图是哑铃状的。输出哑铃的个数。

    举几个例子:

    A、B、C都是哑铃状的图;

    思路:很简单的一道题,首先我们对一个联通块进行树上DFS,说白了是就是那个TarJan树,求出每个以某个节点为根的树的大小,这样DFS只有桥连接的两个点的size 是对的,碰巧,我们也是只需要这两个点的size。顺便我们来求出这个来联通块的边的个数。

    那么我们再进行Tarjan找到桥,即u - - > v,我们只需要判断张图是否是完全图的就行了。、

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 115;
    int T, N, M;
    int ans = 0;
    struct Edge
    {
        int to, next;
        Edge(int to = 0, int next = 0): to(to), next(next) {}
    } E[10050];
    int head[maxn], tot;
    void initedge()
    {
        for(int i = 0; i <= N; i++) head[i] = -1;
        tot = 0;
    }
    void addedge(int u, int v)
    {
        E[tot] = Edge(v, head[u]);
        head[u] = tot++;
    }
    int pre[maxn], low[maxn], dfsclock;
    int sz[maxn], edg;
    int DFS(int u, int fa)
    {
        sz[u] = 1;
        int ret = 0;
        for(int k = head[u]; ~k; k = E[k].next)
        {
            ret += 1;
            int v = E[k].to;
            if(v == fa || sz[v]) continue;
            ret += DFS(v, u);
            sz[u] += sz[v];
        }
        return ret;
    }
    bool Tarjan(int u, int fa)
    {
        pre[u] = low[u] = ++dfsclock;
        for(int k = head[u]; ~k; k = E[k].next)
        {
            int v = E[k].to;
            if(v == fa) continue;
            if(!pre[v])
            {
                if(Tarjan(v, u)) return true;
                low[u] = min(low[u], low[v]);
                if(low[v] > pre[u])
                {
                    int sum = sz[v] * (sz[v] - 1) + 1;
                    if(sum == edg) return true;
                }
            }
            else
                low[u] = min(low[u], pre[v]);
        }
        return false;
    }
    void TarjanInit()
    {
        for(int i = 1; i <= N; i++)
            pre[i] = sz[i] = 0;
        dfsclock = ans = 0;
        for(int i = 1; i <= N; i++)
        {
            if(!pre[i])
            {
                edg = DFS(i, i);
                edg /= 2;
                if(Tarjan(i, i)) ans++;
            }
        }
    }
    int main ()
    {
        int ic = 0;
        scanf("%d", &T);
        while(T--)
        {
            scanf("%d %d", &N, &M);
            initedge();
            for(int i = 1; i <= M; i++)
            {
                int u, v;
                scanf("%d %d", &u, &v);
                addedge(u, v);
                addedge(v, u);
            }
            TarjanInit();
            printf("Case #%d: %d
    ", ++ic, ans);
        }
        return 0;
    }
    想的太多,做的太少。
  • 相关阅读:
    作业3月30号
    21、,模块与包的使用
    作业3月26号
    20、面向函数与匿名函数及模块
    作业3月25号
    19、迭代器及函数的递归调用
    作业3月24号
    06-函数
    3.17---购物车练习
    3.15---文件处理练习2
  • 原文地址:https://www.cnblogs.com/pealicx/p/7259478.html
Copyright © 2020-2023  润新知