• E


    题意:给一个图,想让每两个点之间都有两条路相连,不过特殊的是相同的两点之间多次相连被认为是一条边,现在求最少还需要添加几条边才能做到
    分析:手欠没看清楚是相同的边只能相连一次,需要去重边,缩点后求出来叶子节点的数目即可。
    ***********************************************************************
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    using namespace std;

    const int MAXN = 1e5+5;

    struct Edge{int v, next;}e[MAXN];
    int Head[MAXN], cnt;
    void AddEdge(int u, int v)
    {
        e[cnt].v = v;
        e[cnt].next = Head[u];
        Head[u] = cnt++;
    }

    int low[MAXN], dfn[MAXN], Index;
    int Stack[MAXN], top;
    int belong[MAXN], bnt;
    int ru[MAXN];
    bool use[5005][5005];

    void InIt(int N)
    {
        cnt = Index = top = bnt = 0;
        memset(use, 0sizeof(use));
        for(int i=1; i<=N; i++)
        {
            Head[i] = -1;
            dfn[i] = 0;
            ru[i] = 0;
        }
    }
    void Tarjan(int u, int father)
    {
        int v;

        low[u] = dfn[u] = ++Index;
        Stack[++top] = u;

        for(int j=Head[u]; j != -1; j=e[j].next)
        {
            v = e[j].v;
            if( !dfn[v] )
            {
                Tarjan(v, u);
                low[u] = min(low[u], low[v]);
            }
            else if(v != father)
                low[u] = min(low[u], dfn[v]);
        }

        if(low[u] == dfn[u])
        {
            ++bnt;
            do
            {
                v = Stack[top--];
                belong[v] = bnt;
            }
            while( u != v );
        }
    }

    int main()
    {
        int N, M;

        while(scanf("%d%d", &N, &M) != EOF)
        {
            int i, j, u, v;

            InIt(N);

            while(M--)
            {
                scanf("%d%d", &u, &v);

                if(use[u][v] == false)
                {
                    AddEdge(u, v);
                    AddEdge(v, u);
                    use[u][v] = use[v][u] = true;
                }
            }

            Tarjan(11);

            for(i=1; i<=N; i++)
            for(j=Head[i]; j!=-1; j=e[j].next)
            {
                if(belong[i] != belong[e[j].v])
                {
                    ru[ belong[i] ]++;
                }
            }

            int ans = 0;

            for(i=1; i<=bnt; i++)
            {
                if(ru[i] == 1)
                    ans++;
            }

            printf("%d ", (ans+1)>>1);
        }

        return 0; 

    }

  • 相关阅读:
    OpenCV开发笔记(五十八):红胖子8分钟带你深入了解图像的矩(图文并茂+浅显易懂+程序源码)
    Oracle数据迁移后由列的直方图统计信息引起的执行计划异常
    oracle统计信息的锁定与解锁
    [统计信息系列7] Oracle 11g的自动统计信息收集
    [统计信息系列6] 数据字典统计信息
    [统计信息系列5] 系统统计信息
    MongoDB创建与删除集合(collection)
    MongoDB创建与删除数据库
    [统计信息系列4] 列的统计信息
    [统计信息系列3] 索引的统计信息
  • 原文地址:https://www.cnblogs.com/liuxin13/p/4692960.html
Copyright © 2020-2023  润新知