zoukankan      html  css  js  c++  java
  • UVA 796 Critical Links (tarjan算法求割边)

      这是在kuangbin的题目里看到的,不得不吐槽一下,题目中居然没给出数据范围,还是我自己猜的~本来是一道挺裸的题,但是我wa了好多次,原因就是这里面有两个坑点,1重边特判,2输出时左边必须比右边小。

    但是我之前说过,在判断割边的时候只需要直接记录就可以了,因为每条边只会访问一次,但其实这是取决于建图方式的,题目中给出了每个点都与之相连的点,所以我们建出的边一定会有重复的,所以需要用map去重一下,可以在建图的时候就判断(因为没有多重边),也可以在收集割边的时候判断。代码如下:

    #include<map>
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    map<int,int>ma;
    #define maxn 10010
    struct EDGE
    {
        int to,nxt;
    } edge[10*maxn];
    int tot,n,dfn[maxn],low[maxn],head[maxn],all,resnum;
    void add_edge(int u,int v)
    {
        edge[tot].to = v;
        edge[tot].nxt = head[u];
        head[u] = tot++;
    }
    void init()
    {
        memset(low,0,sizeof(low));
        memset(dfn,0,sizeof(dfn));
        all = 0;
        resnum = 0;
        ma.clear();
    }
    bool mul(int u,int v)
    {
        if(ma[u*maxn+v] || ma[v*maxn+u]) return true;
        ma[u*maxn+v] = ma[v*maxn+u] = 1;
        return false;
    }
    struct Node
    {
        int x,y;
    };
    Node out[maxn];
    void tarjan(int u,int fa)
    {
        dfn[u] = low[u] = ++all;
        for(int i = head[u]; i != -1; i = edge[i].nxt)
        {
            int v = edge[i].to;
            if(!dfn[v])
            {
                tarjan(v,u);
                low[u] = min(low[u],low[v]);
                if(low[v] > dfn[u])
                {
                    if(!mul(u,v))
                    {
                        int tmpu = u,tmpv = v;
                        if(tmpu > tmpv)
                            swap(tmpu,tmpv);
                        out[resnum].x = tmpu;
                        out[resnum].y = tmpv;
                        resnum++;
                    }
                }
            }
            else if(v != fa) low[u] = min(low[u],dfn[v]);
        }
        return ;
    }
    bool cmp(Node a,Node b)
    {
        if(a.x != b.x) return a.x < b.x;
    }
    int getnum(char *a)
    {
        int lena = strlen(a);
        int num = 0,jw = 1;
        for(int i = 1; i < lena; i++)
        {
            if(a[i] == ')')
            {
                for(int j = i-1; j > 0; j--)
                {
                    num += (a[j]-'0')*jw;
                    jw *= 10;
                }
                // cout<<"num = "<<num<<endl;
                return num;
            }
        }
    }
    int main()
    {
        int ans,m,x,y;
        while(~scanf("%d",&n))
        {
            tot = 0;
            memset(head,-1,sizeof(head));
            for(int i = 0; i < n; i++)
            {
                scanf("%d",&x);
                char op[220];
                scanf("%s",op);
                int m = getnum(op);
                for(int j = 0; j < m; j++)
                {
                    scanf("%d",&y);
                    add_edge(x,y);
                    add_edge(y,x);
                }
            }
            init();
            for(int i = 0; i < n; i++)
            {
                if(!dfn[i]) tarjan(i,-1);
            }
            sort(out,out+resnum,cmp);
            printf("%d critical links
    ",resnum);
            for(int i = 0; i < resnum; i++)
            {
                printf("%d - %d
    ",out[i].x,out[i].y);
            }
            puts("");
        }
        return 0;
    }
  • 相关阅读:
    从实战角度超级详解中大型企业微服务化的六大核心关键技术
    Web API 入门的相关文章
    发布asp.net core3.1 web api to IIS
    web api 起步之一
    工作中常见的一些英语
    SSIS--Excel Demo
    SSIS中常用的一些Task组件
    企业系统上Azure的建议与注意事项
    POST提交时防止密码泄漏
    转 Netbackup用于技术支持的问题报告(报障模版)
  • 原文地址:https://www.cnblogs.com/jifahu/p/5527589.html
Copyright © 2011-2022 走看看