zoukankan      html  css  js  c++  java
  • 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; 

    }

  • 相关阅读:
    BZOJ 1143 [CTSC2008]祭祀river
    BZOJ 3997 [TJOI2015]组合数学
    BZOJ 3996 [TJOI2015]线性代数
    BZOJ 4553 [Tjoi2016&Heoi2016]序列
    微信开发之密文模式 mcrypt_module_open 走不过
    JS JSON & ARRAY 遍历
    linux ftp服务器配置(Ubuntu)
    thinkphp 吐槽篇
    游戏--疯狂猜字随机混乱正确答案逻辑
    PHP 批量去除BOM头;此文转载;
  • 原文地址:https://www.cnblogs.com/liuxin13/p/4692960.html
Copyright © 2011-2022 走看看