poj3177Redundant Paths tarjan缩点

Posted lxjshuju

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj3177Redundant Paths tarjan缩点相关的知识,希望对你有一定的参考价值。

//给一个连通图,问最少须要加入多少条边才干使得
//随意两个点都有两条不同的路走到
//对于一个强连通分量的全部随意两点都能有两点能够到达
//先用tarjan缩点,缩点以后就是一棵树,对于这个树考虑有几个
//叶子节点 ans = (leaf+1)/2
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std ;
const int maxn = 10010 ;
int dfn[maxn] , low[maxn] , vis[maxn] ;
int stack[maxn],isstack[maxn] , belong[maxn] ;
int head[maxn] ;int n, m ;
int step , nedge , num , top ;
struct Edge
{
    int v ;
    int next ;
}edge[maxn<<1] ;
void addedge(int u , int v)
{
    edge[nedge].v = v ;
    edge[nedge].next = head[u]  ;
    head[u] = nedge++ ;
}
void init()
{
    memset(head , - 1 , sizeof(head)) ;
    memset(dfn , 0 , sizeof(dfn)) ;
    memset(isstack , 0 , sizeof(isstack)) ;
    memset(vis , 0  ,sizeof(vis)) ;
    step = nedge = num = top = 0;
}
void tarjan(int u , int pre)
{
    stack[++top] = u ;
    isstack[u] = 1 ;
    dfn[u] = low[u] = ++step;
    for(int i = head[u] ;i != -1 ;i = edge[i].next)
    {
       int v = edge[i].v ;
       if(pre == i)continue ;
       if(!dfn[v])
       {
           tarjan(v , i^1) ;
           low[u] = min(low[u] , low[v]) ;
       }
       else if(isstack[v])
       low[u] = min(low[u] , dfn[v]) ;
    }
    if(low[u] == dfn[u])
    {
        int v = -1 ;
        num++ ;
        while(u != v)
        {
            v = stack[top--] ;
            isstack[v] = 0 ;
            belong[v] = num ;
        }
    }
}
int main()
{
    while(~scanf("%d%d" , &n , &m))
    {
        init() ;
        while(m--)
        {
            int u , v ;
            scanf("%d%d" , &u , &v) ;
            addedge(u , v) ;
            addedge(v, u) ;
        }
        tarjan(1, -1) ;
        for(int i = 1;i <= n;i++)
          for(int j = head[i] ; j != -1 ; j = edge[j].next)
          {
              int u = belong[i] ;
              int v = belong[edge[j].v] ;
              if(u == v)continue ;
              vis[u]++ ;
          }
        int ans = 0;
        for(int i = 1;i <= n;i++)
        if(vis[i] == 1)
        ans++ ;
        cout<<(ans+1)/2<<endl;
    }
}

以上是关于poj3177Redundant Paths tarjan缩点的主要内容,如果未能解决你的问题,请参考以下文章

POJ3177 Redundant Paths 双连通分量

无向图缩点poj3177 Redundant Paths

[双连通分量] POJ 3177 Redundant Paths

poj3177:Redundant Paths——题解

Redundant Paths POJ - 3177(边双连通)

POJ 3177 Redundant Paths