码迷,mamicode.com
首页 > 其他好文 > 详细

poj3177Redundant Paths tarjan缩点

时间:2015-08-10 13:37:50      阅读:94      评论:0      收藏:0      [点我收藏+]

标签: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缩点

标签:tarjan

原文地址:http://blog.csdn.net/cq_pf/article/details/47396947

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!