zoukankan      html  css  js  c++  java
  • poj 3352 Road Construction(边双连通)

    题意:一个国家有N个城市,有M条路连接这N个城市,通过这些路任意两个城市都可以互达,现在为了游客的安全,决定重新修葺一下这些路,但是为了能方便游客,需要新修一些路,使得任意两城市间都有两条路。

    思路:先求强连通分支,然后缩点,这样就形成了一个树,找到叶子节点ans,只要修(ans+1)/2条路就可以达到目的了。

    代码:

    View Code
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <math.h>
    #include <stack>
    #define  N 1005
    using namespace std ;
    
    struct node
    {
        int e , next ;
    }p[2*N];
    
    int dfn[N] , low[N] , out[N] , head[N] ;
    int n , m , cnt , id , num , ans ;
    
    //求强连通分支
    void dfs( int x , int fa )
    {
        dfn[x] = low[x] = ++id ;
    
        for ( int i = head[x] ; i != -1 ; i = p[i].next )
        {
            int v = p[i].e ;
            if ( v != fa && !dfn[v] )
            {
                dfs( v , x ) ;
                low[x] = min( low[x] , low[v]);
                if ( low[v] > dfn[x] )
                {
                    cnt++;
                }
            }
            else if ( v != fa && low[x] > dfn[v] )
            low[x] = dfn[v] ;
        }
    }
    
    int main()
    {
        int i , j , x , y ;
    
        while ( scanf ( "%d%d" , &n , &m ) != EOF )
        {
            //建图
            memset( head , -1 , sizeof( head )) ;
            num = 0 ;
            for ( i = 1 ; i <= m ; i++ )
            {
                scanf ( "%d%d" , &x , &y ) ;
                p[num].e = y ;
                p[num].next = head[x] ;
                head[x] = num++ ;
    
                p[num].e = x ;
                p[num].next = head[y] ;
                head[y] = num++ ;
            }
            
            //初始化
            cnt = id = ans = 0 ;
            memset( out , 0 , sizeof ( out )) ;
            
            //缩点
            dfs ( 1 , -1 ) ;
            
            //找叶子节点,度为1的为叶子节点
            for ( i = 1 ; i <= n ; i++ )
            {
                for ( j = head[i] ; j != -1 ; j = p[j].next )
                {
                    int v = p[j].e ;
                    if ( low[i] != low[v] )
                    {
                        out[low[i]]++ ;
                    }
                }
            }
            for ( i = 1 ; i <= n ; i++)
            if ( out[i] == 1 )
            ans++ ;
    
            printf ( "%d\n" , ( ans + 1 ) / 2 ) ;
        }
        return 0 ;
    }
  • 相关阅读:
    Android Studio快速定位当前文件所在的位置
    LeetCode:Search Insert Position
    apk当安装程序将文件复制到手机自带的指定文件夹
    《UNIX级别编程环境》注意读出信号(2)
    iOS:删除小程序
    百度CSND博客在搜索栏中显示图片
    HDU4893:Wow! Such Sequence!(段树lazy)
    Google I/O 2014? No,Android I/O 2014
    Android Push Notifications using Google Cloud Messaging (GCM), PHP and MySQL
    自己动手写CPU 笔记
  • 原文地址:https://www.cnblogs.com/misty1/p/2768283.html
Copyright © 2011-2022 走看看