zoukankan      html  css  js  c++  java
  • ZOJ 2588 Burning Bridges (tarjan求割边)

    题目链接

    题意 : N个点M条边,允许有重边,让你求出割边的数目以及每条割边的编号(编号是输入顺序从1到M)。

    思路 :tarjan求割边,对于除重边以为中生成树的边(u,v),若满足dfn[u] < low[v],则边(u,v)是割边。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 
     6 using namespace std;
     7 
     8 struct node
     9 {
    10     int u ;
    11     int v;
    12     int next ;
    13     int num ;
    14 }p[200100];
    15 int dfn[200100],low[200100] ;//dfn深度优先遍历生成树的顺序,low表示该节点能够到达的祖先的最小编号
    16 int bridge[200100] ,nbrid,vis[200010];//桥的编号,割边的条数,vis表示该点是否访问过
    17 int cnt,head[200100],tot ;
    18 
    19 void Init()
    20 {
    21     cnt = nbrid = tot= 0 ;
    22     memset(head,-1,sizeof(head)) ;
    23     memset(vis,0,sizeof(vis)) ;
    24 }
    25 void addedge(int u,int v,int id)
    26 {
    27     //p[cnt].u = u ;
    28     p[cnt].v = v ;
    29     p[cnt].num = id ;
    30     p[cnt].next = head[u] ;
    31     head[u] = cnt ++ ;
    32     //p[cnt].u = v ;
    33     p[cnt].v = u ;
    34     p[cnt].num = id ;
    35     p[cnt].next = head[v] ;
    36     head[v] = cnt ++ ;
    37 }
    38 
    39 void DFS(int u,int fu)
    40 {
    41     dfn[u] = low[u] = tot++ ;
    42     vis[u] = 1 ;
    43     for(int i = head[u] ; i != -1 ; i = p[i].next)
    44     {
    45         int v = p[i].v;
    46         if(p[i].num != fu && vis[v] )
    47         {
    48             low[u] = min(low[u],dfn[v]) ;
    49         }
    50         else if( !vis[v] )
    51         {
    52             DFS(v,p[i].num) ;
    53             low[u] = min(low[u],low[v]) ;
    54             if(low[v] > dfn[u])
    55             {
    56                 bridge[++nbrid] = p[i].num;
    57             }
    58         }
    59     }
    60 }
    61 int main()
    62 {
    63     int T ,N,M,u,v;
    64     scanf("%d",&T) ;
    65     while(T--)
    66     {
    67         Init() ;
    68         scanf("%d %d",&N,&M) ;
    69         for(int i = 1 ; i <= M ; i++)
    70         {
    71             scanf("%d %d",&u,&v) ;
    72             addedge(u,v,i) ;
    73         }
    74         DFS(1,-1) ;
    75         sort(bridge+1,bridge+1+nbrid) ;
    76         printf("%d
    ",nbrid) ;
    77         for(int i = 1 ; i <= nbrid ; i++)
    78         {
    79             if(i != nbrid)
    80             printf("%d ",bridge[i]) ;
    81             else printf("%d
    ",bridge[i]) ;
    82         }
    83         if(T)puts("") ;
    84     }
    85     return 0;
    86 }
    View Code

    鹏哥说我那样写的太丑了,非给我改成下边的样子

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 
     6 using namespace std;
     7 
     8 struct node
     9 {
    10     int u ;
    11     int v;
    12     int next ;
    13     int num ;
    14 }p[200100];
    15 int dfn[200100],low[200100] ;
    16 int bridge[200100] ,nbrid,vis[200010];
    17 int cnt,head[200100],tot ;
    18 int fb[200100];
    19 void Init()
    20 {
    21     cnt = nbrid = tot= 0 ;
    22     memset(head,-1,sizeof(head)) ;
    23     memset(vis,0,sizeof(vis)) ;
    24     memset(fb,0,sizeof(fb));
    25     memset(dfn,0,sizeof(dfn));
    26     memset(low,0,sizeof(low));
    27 }
    28 void addedge(int u,int v,int id)
    29 {
    30     //p[cnt].u = u ;
    31     p[cnt].v = v ;
    32     p[cnt].num = id ;
    33     p[cnt].next = head[u] ;
    34     head[u] = cnt ++ ;
    35     //p[cnt].u = v ;
    36     p[cnt].v = u ;
    37     p[cnt].num = id ;
    38     p[cnt].next = head[v] ;
    39     head[v] = cnt ++ ;
    40 }
    41 void DFS(int u)
    42 {
    43     dfn[u] = low[u] = ++tot;
    44     //vis[u] = 1 ;
    45     for(int i = head[u] ; i != -1 ; i = p[i].next)
    46     {
    47         int v=p[i].v;
    48         if(fb[i^1])continue;
    49         fb[i]=1;
    50         if(dfn[v] )//如果该点没被访问过dfn自然为0,所以不用vis数组也可
    51         {
    52             low[u] = min(low[u],dfn[v]) ;
    53         }
    54         else
    55         {
    56             DFS(v) ;
    57             low[u] = min(low[u],low[v]) ;
    58             if(low[v] > dfn[u])
    59             {
    60                 bridge[++nbrid] = p[i].num;
    61             }
    62         }
    63     }
    64 }
    65 int main()
    66 {
    67     int T ,N,M,u,v;
    68     scanf("%d",&T) ;
    69     while(T--)
    70     {
    71         Init() ;
    72         scanf("%d %d",&N,&M) ;
    73         for(int i = 1 ; i <= M ; i++)
    74         {
    75             scanf("%d %d",&u,&v) ;
    76             addedge(u,v,i) ;
    77         }
    78         DFS(1) ;
    79         sort(bridge+1,bridge+1+nbrid) ;
    80         printf("%d
    ",nbrid) ;
    81         for(int i = 1 ; i <= nbrid ; i++)
    82         {
    83             if(i != nbrid)
    84             printf("%d ",bridge[i]) ;
    85             else printf("%d
    ",bridge[i]) ;
    86         }
    87         if(T)puts("") ;
    88     }
    89     return 0;
    90 }
    View Code
  • 相关阅读:
    openstack 介绍
    python实现图片批量剪裁的程序
    iOS开发多线程篇—GCD介绍
    block代码块介绍
    ios中的界面跳转方式
    NSNotificationCenter消息机制的介绍
    ios的手势操作之UIGestureRecognizer浅析
    collectionViewFlow的界面编写
    UITableView的简单应用介绍
    滚动视图创建
  • 原文地址:https://www.cnblogs.com/luyingfeng/p/3905188.html
Copyright © 2011-2022 走看看