• hdu 3394 Railway


    这是一道用tarjin求双连通分量的题;

    其中,不需要修的道路就是桥的数目;

    在图的每个极大环中,如果点的数目小于边的数目,显然这个环中含有子环,并且这个环的边数就是这个环中有冲突的边的数目;

    如果点的数模等于边的数目,那就没有冲突;

    代码:

     1 #include<cstdio>
     2 #include<vector>
     3 #include<cstring>
     4 using namespace std;
     5 #define maxn 10005
     6 
     7 vector<int>g[maxn];
     8 int block[maxn],top,stack[maxn],dfn[maxn],low[maxn],index,res1,res2;
     9 bool instack[maxn],vis[maxn];
    10 
    11 void count_edge()
    12 {
    13     memset(vis,0,sizeof vis);
    14     for(int i=1; i<=block[0]; i++)
    15         vis[block[i]]=1;
    16     int sum=0;
    17     for(int i=1; i<=block[0]; i++)
    18     {
    19         int w=block[i];
    20         for(int j=0; j<g[w].size(); j++)
    21             if(vis[g[w][j]])
    22                 sum++;
    23     }
    24     sum/=2;//这个块中的边数
    25     if(sum<block[0])
    26         res1+=sum;
    27     if(sum>block[0])
    28         res2+=sum;
    29 }
    30 void tarjan(int v)
    31 {
    32     dfn[v]=low[v]=++index;
    33     stack[++top]=v;
    34     instack[v]=true;
    35     for(int i=0; i<g[v].size(); i++)
    36     {
    37         int w=g[v][i];
    38         if(!dfn[w])
    39         {
    40             tarjan(w);
    41             low[v]=min(low[v],low[w]);
    42             if(low[w]>=dfn[v])
    43             {
    44                 block[0]=0;
    45                 while(1)
    46                 {
    47                     block[++block[0]]=stack[top];
    48                     instack[stack[top]]=0;
    49                     if(stack[top--]==w)break;
    50                 }
    51                 block[++block[0]]=v;
    52                 count_edge();
    53             }
    54         }
    55         else if(instack[w])
    56             low[v]=min(low[v],dfn[w]);
    57     }
    58 }
    59 
    60 int main ()
    61 {
    62     int n,m,x,y;
    63     while(scanf("%d%d",&n,&m)==2 && n+m)
    64     {
    65         for(int i=0; i<n; i++)g[i].clear();
    66         for(int i=0; i<m; i++)
    67         {
    68             scanf("%d%d",&x,&y);
    69             g[x].push_back(y);
    70             g[y].push_back(x);
    71         }
    72         memset(dfn,0,sizeof dfn);
    73         memset(low,0,sizeof low);
    74         memset(instack,0,sizeof instack);
    75         top=index=res1=res2=0;
    76         for(int i=0; i<n; i++)if(!dfn[i])tarjan(i);
    77         printf("%d %d
    ",res1,res2);
    78     }
    79     return 0;
    80 }
    View Code
  • 相关阅读:
    Spring中常见的设计模式——工厂模式
    Java编程思想——第14章 类型信息(二)反射
    Java编程思想——第17章 容器深入研究(二)
    Java编程思想——第17章 容器深入研究(一)
    python笔记-正则表达式常用函数
    python笔记-文件读写
    AWK编程
    ORA-01555错误
    group_concat的使用
    expect-调试模式的使用
  • 原文地址:https://www.cnblogs.com/yours1103/p/3303171.html
Copyright © 2020-2023  润新知