zoukankan      html  css  js  c++  java
  • ZOJ 2588 Burning Bridges

    求哪几条边是桥,用Tarjan算法,注意重边的处理。

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<vector>
    #include<algorithm>
    using namespace std;
    
    const int maxn=10000+10; //结点数量
    const int Maxn=2*100000+10; //边的数量
    int low[maxn];
    int dfn[maxn];
    struct Edge
    {
        int from;
        int to;
        int id;
        int ans;//ans为1,表示这条边是割边
    } edge[Maxn];
    vector<int>G[maxn];
    int Ans[Maxn];
    int N,M;//N个结点,M条边
    int tmpdfn;
    int tot;
    
    void init()
    {
        for(int i=0; i<maxn; i++) G[i].clear();
        memset(low,0,sizeof(low));
        memset(dfn,0,sizeof(dfn));
        low[1]=dfn[1]=1;
        tmpdfn=0;
        tot=0;
    }
    
    int dfs(int u,int id)
    {
        tmpdfn++;
        int lowu=dfn[u]=tmpdfn;
        for(int i=0; i<G[u].size(); i++)
        {
            int B=G[u][i];
            if(!dfn[edge[B].to])
            {
                int lowv=dfs(edge[B].to,edge[B].id);
                lowu=min(lowu,lowv);
                if(lowv>dfn[u]) edge[B].ans=1;
            }
            else if(dfn[edge[B].to])
            {
                if(edge[B].id/2==id/2) continue;
                lowu=min(lowu,dfn[edge[B].to]);
            }
        }
        low[u]=lowu;
        return lowu;
    }
    
    void AddEdge(int u,int v)
    {
        edge[tot].from=u;
        edge[tot].to=v;
        edge[tot].id=tot;
        edge[tot].ans=0;
        G[u].push_back(tot);
        tot++;
    
        edge[tot].from=v;
        edge[tot].to=u;
        edge[tot].id=tot;
        edge[tot].ans=0;
        G[v].push_back(tot);
        tot++;
    }
    
    int main()
    {
        int T_T;
        scanf("%d",&T_T);
        while(T_T--)
        {
            scanf("%d%d",&N,&M);
            init();
            for(int i=0; i<M; i++)
            {
                int u,v;
                scanf("%d%d",&u,&v);
                AddEdge(u,v);
            }
    
            dfs(1,-1);
    
            int ans=0;
            for(int i=0; i<2*M; i++)
                if(edge[i].ans)
                {
                    Ans[ans]=edge[i].id/2+1;
                    ans++;
                }
            printf("%d
    ",ans);
            for(int i=0; i<ans; i++)
            {
                if(i<ans-1) printf("%d ",Ans[i]);
                else printf("%d
    ",Ans[i]);
            }
            if(T_T>=1) printf("
    ");
        }
        return 0;
    }
  • 相关阅读:
    基于Python的人脸动漫转换
    let 与 var的区别
    【LeetCode】汇总
    【HDU】4632 Palindrome subsequence(回文子串的个数)
    【算法】均匀的生成圆内的随机点
    【LeetCode】725. Split Linked List in Parts
    【LeetCode】445. Add Two Numbers II
    【LeetCode】437. Path Sum III
    【LeetCode】222. Count Complete Tree Nodes
    【LeetCode】124. Binary Tree Maximum Path Sum
  • 原文地址:https://www.cnblogs.com/zufezzt/p/4710756.html
Copyright © 2011-2022 走看看