zoukankan      html  css  js  c++  java
  • 「POJ3352」Road Construction

    边双连通分量模板

    求出边双连通分量,缩点后成为一个树。

    若要使得任意一棵树,在增加若干条边后,变成一个双连通图,那么

    至少增加的边数 =( 这棵树总度数为1的结点数 + 1 )/ 2

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<vector>
     4 using namespace std;
     5 const int N=1010;
     6 int n,m;
     7 vector<int>g[N];
     8 int dfn[N],low[N],timer,sta[N],top,cnt,d[N],ans,color[N];
     9 bool gg[N][N];
    10 void tarjan(int k,int fa){
    11     dfn[k]=low[k]=++timer;
    12     sta[top++]=k;
    13     for(int i=0;i<g[k].size();i++){
    14         int x=g[k][i];
    15         if(x==fa) continue;
    16         if(!dfn[x]){
    17             tarjan(x,k);
    18             low[k]=min(low[k],low[x]);
    19         }else if(dfn[x]<dfn[k]) low[k]=min(low[k],dfn[x]);
    20     }
    21     if(low[k]==dfn[k]){
    22         cnt++;
    23         while(sta[top]!=k) top--,color[sta[top]]=cnt;
    24     }
    25     return;
    26 }
    27 int main(){
    28     int t1,t2;
    29     scanf("%d%d",&n,&m);
    30     for(int i=1;i<=m;i++){
    31         scanf("%d%d",&t1,&t2);
    32         g[t1].push_back(t2);g[t2].push_back(t1);
    33     }
    34     tarjan(1,0);
    35     for(int i=1;i<=n;i++)
    36         for(int j=0;j<g[i].size();j++){
    37             int x=g[i][j];
    38             if(color[x]!=color[i]&&!gg[color[i]][color[x]])
    39                 d[color[x]]++,d[color[i]]++,gg[color[i]][color[x]]=gg[color[x]][color[i]]=1;
    40         }
    41     for(int i=1;i<=cnt;i++) if(d[i]==1) ans++;
    42     printf("%d",(ans+1)/2);
    43     return 0;
    44 }
  • 相关阅读:
    C到C++的升级
    设计模式分类
    对模式的十大误解
    MAC帧和IP包的分析
    python之路—从入门到放弃
    选课系统
    Scrapy框架详解
    爬虫系列
    Python从入门到断气
    常用模块
  • 原文地址:https://www.cnblogs.com/mycups/p/8527903.html
Copyright © 2011-2022 走看看