• ZOJ2588 求桥


    /*
    *State: ZOJ2588 530 MS    12788 KB    GNU C++
    *题目大意:
    *        给出一个无向图,输入n(表示n个定点,1~n), m(m条边,有重边),
    *        (2 <= N <= 10 000, 1 <= M <= 100 000),求这个无向图中的桥,
    *        并输出桥属于输入中边的id.
    *解题思路:
    *        知道求割点与求割边是很相似的,自己用笔模拟一下就知道,如果
    *        存在low[v] > dfn[u].那么uv就是割边。看似与割点异常类似,但是
    *        用了原始的求割点的tarjan敲了几遍后发现,不行。因为求割点的时
    *        候由于条件是low[v] >= dfn[u],所以它可能回溯回自己的父亲节点,
    *        然后就更新了自己的low[v].之后求割边的条件就实现不出来了。
    *
    *        发现了这个问题之后,就修改了tarjan算法,把参数由一个当前节点
    *        改为2个,一个父亲结点,一个它自己,然后搜。将一个节点的所有孩
    *        子节点都搜一遍,之后再判断,只要dfn[n] == low[n],就说明n跟它
    *        的父亲节点构成的边是割边。为什么?因为dfn[n] == low[n],就说明
    *        当前节点n的所有孩子节点都最多只能到达当前节点n的孩子节点。也就
    *        是说n跟它的father是关节边。
    *
    *        ps:为什么求割点是把判断放在循环内,求割边要放在循环外(其实放
    *        循环外面也可以,但是要注意回溯判断的不同,要修改根节点的情况)。
    *        用笔模拟下即可。该题有重边,我先把它当无重边算,之后在判断割边
    *        的时候判断下是否为重边即可。
    */
    View Code
    #include <iostream>
    #include <vector>
    #include <cstdio>
    #include <algorithm>
    #include <utility>
    #include <cstring>
    using namespace std;
    
    typedef struct _node
    {
        int v, id, num;
        _node():num(0) {};
    }N;
    
    const int MAX = 10005;
    vector<N> vec[MAX];
    int dfn[MAX], low[MAX], step, id;
    int ans[MAX * 10], cnt;
    
    void addEdge(int u, int v)
    {
        bool flag = false;
        for(unsigned i = 0; i < vec[u].size(); i++)
        {
            if(vec[u][i].v == v)
            {
                flag = true;
                vec[u][i].num++;
                for(unsigned j = 0; j < vec[v].size(); j++)
                {
                    if(vec[v][j].v == u)
                    {
                        vec[v][j].num++;
                        break;
                    }
                }
                id++;
                break;
            }
        }
        if(flag == false)
        {
            N tmp;
            tmp.v = v, tmp.id = id++;
            tmp.num = 1;
            vec[u].push_back(tmp);
            tmp.v = u;
            vec[v].push_back(tmp);
        }
    }
    
    void tarjan(int father, int n)
    {
        dfn[n] = low[n] = ++step;
        for(unsigned i = 0; i < vec[n].size(); i++)
        {
            int son = vec[n][i].v;
            if(dfn[son] == -1)
            {
                tarjan(n, son);
                low[n] = min(low[n], low[son]);
            }
            else if(son != father)
                low[n] = min(low[n], dfn[son]);
        }
    
        if(dfn[n] == low[n])
        {
            int son = n;
            n = father;
            for(unsigned k = 0; k < vec[n].size(); k++)
            {
                if(son == vec[n][k].v)
                {
                    if(vec[n][k].num == 1)
                    {
                        ans[cnt++] = vec[n][k].id;
                    }
                    break;
                }
            }
        }
    }
    
    void init()
    {
        id = 1;
        step = cnt = 0;
        for(int i = 0; i < MAX; i++)
        {
            vec[i].clear();
            dfn[i] = low[i] = -1;
        }
    }
    
    int main(void)
    {
    #ifndef ONLINE_JUDGE
        //freopen("in.txt", "r", stdin);
    #endif
    
        int cas;
        scanf("%d", &cas);
        while(cas--)
        {
            init();
            int n, m;
            scanf("%d %d", &n, &m);
            for(int i = 0; i < m; i++)
            {
                int u, v;
                scanf("%d %d", &u, &v);
                addEdge(u, v);
            }
            dfn[1] = low[1] = ++step;
            tarjan(1, 1);
    
            printf("%d\n", cnt);
            if(cnt)
            {
                sort(ans, ans + cnt);
                printf("%d", ans[0]);
                for(int i = 1; i < cnt; i++)
                {
                    printf(" %d", ans[i]);
                }
                printf("\n");
            }
            if(cas)
                printf("\n");
        }
        return 0;
    }
  • 相关阅读:
    Eclipse / android studio 添加第三方jar包 步骤
    Android checkbox 自定义点击效果
    Android 程序打包和安装过程
    Android 基础
    (转)Genymotion安装virtual device的“unable to create virtual device, Server returned Http status code 0”的解决方法
    (转)eclipse 导入Android 项目 步骤
    微信开放平台注册 步骤
    Android Studio 初级安装
    数组
    作用域问题代码
  • 原文地址:https://www.cnblogs.com/cchun/p/2645077.html
Copyright © 2020-2023  润新知