zoukankan      html  css  js  c++  java
  • POJ 3177 Redundant Paths(Tarjan)

    题目链接

    题意 : 一个无向连通图,最少添加几条边使其成为一个边连通分量 。

    思路 :先用Tarjan缩点,缩点之后的图一定是一棵树,边连通度为1。然后找到所有叶子节点,即度数为1的节点的个数leaf,最后要添加的边的条数就是(leaf+1)/2 ;

     1 // 3177
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <iostream>
     5 #include <algorithm>
     6 
     7 using namespace std ;
     8 
     9 int head[101010],fb[101010],low[101010],dfn[101010] ,degree[101010];
    10 int cnt,timee ,ans ;
    11 struct node
    12 {
    13     int u ;
    14     int v ;
    15     int next ;
    16 }p[101010];
    17 
    18 void tarjan(int u)
    19 {
    20     dfn[u] = low[u] = ++timee  ;
    21     for(int i = head[u] ; i != -1 ; i = p[i].next)
    22     {
    23         int v = p[i].v ;
    24         if(fb[i^1]) continue ;
    25         fb[i] = 1 ;
    26         if(dfn[v])  low[u] = min(low[u],dfn[v]) ;
    27         else
    28         {
    29             tarjan(v) ;
    30             low[u] = min(low[v],low[u]) ;
    31             //if(low[v] > dfn[u])
    32             //    ans /++ ;
    33         }
    34     }
    35 }
    36 void Init()
    37 {
    38     cnt = timee = ans = 0 ;
    39     memset(head,-1,sizeof(head)) ;
    40     memset(dfn,0,sizeof(dfn)) ;
    41     memset(low,0,sizeof(low)) ;
    42     memset(fb,0,sizeof(fb)) ;
    43     memset(degree,0,sizeof(degree)) ;
    44 }
    45 void addedge(int u,int v)
    46 {
    47     p[cnt].u = u ;
    48     p[cnt].v = v ;
    49     p[cnt].next = head[u] ;
    50     head[u] = cnt ++ ;
    51     p[cnt].u = v ;
    52     p[cnt].v = u ;
    53     p[cnt].next = head[v] ;
    54     head[v] = cnt ++ ;
    55 }
    56 int main()
    57 {
    58     int F,R ;
    59     while(scanf("%d %d",&F,&R) != EOF)
    60     {
    61         Init() ;
    62         int x,y ;
    63         for(int i = 0 ; i < R ; i++)
    64         {
    65             scanf("%d %d",&x,&y) ;
    66             addedge(x-1,y-1) ;
    67         }
    68         tarjan(0) ;
    69         for(int i = 0 ; i < F ; i++)
    70         {
    71             for(int j = head[i] ; j != -1 ; j = p[j].next)
    72             {
    73                 if(low[i] != low[p[j].v])
    74                     degree[low[i]] ++ ;
    75                 
    76             }
    77         }
    78         for(int i = 1 ; i <= F ; i ++)//  时间戳是从1开始的,所以low的值是可以到达F的,
    79             if(degree[i] == 1)
    80             ans ++ ;
    81         printf("%d
    ",(ans + 1)/2) ;
    82     }
    83     return 0 ;
    84 }
    View Code
  • 相关阅读:
    asp.net(C#)利用QRCode生成二维码(续)-在二维码图片中心加Logo或图像
    C#中DataTable中的Compute方法使用收集
    c#的DateTime.Now函数详解
    附加数据库失败,拒绝访问
    xml文件绑定chenckbox选择框
    Maximum Xor Secondary(单调栈好题)
    Y(类树形DP)
    Average distance(类树形DP)
    Balls and Boxes (模拟题)
    Party at Hali-Bula(树形DP+判断方案数是否唯一)
  • 原文地址:https://www.cnblogs.com/luyingfeng/p/3925353.html
Copyright © 2011-2022 走看看