• 边双联通分量(构造边双联通图)


      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstdlib>
      4 #include <cmath>
      5 #include <algorithm>
      6 #include <cstring>
      7 #include <stack>
      8 #include <cctype>
      9 #include <queue>
     10 #include <string>
     11 #include <vector>
     12 #include <set>
     13 #include <map>
     14 #include <climits>
     15 #define lson root<<1,l,mid
     16 #define rson root<<1|1,mid+1,r
     17 #define fi first
     18 #define se second
     19 #define ping(x,y) ((x-y)*(x-y))
     20 #define mst(x,y) memset(x,y,sizeof(x))
     21 #define mcp(x,y) memcpy(x,y,sizeof(y))
     22 #define Min(x,y) (x<y?x:y)
     23 #define Max(x,y) (x>y?x:y)
     24 using namespace std;
     25 #define gamma 0.5772156649015328606065120
     26 #define MOD 1000000007
     27 #define inf 0x3f3f3f3f
     28 #define N 11005
     29 #define maxn 5005
     30 typedef long long LL;
     31 typedef pair<int,int> PII;
     32 
     33 stack<int>sk;
     34 int n,m,hcnt,deep,block,leaf;
     35 int d[maxn],dfn[maxn],low[maxn],head[maxn];
     36 int color[maxn],vis[maxn];
     37 struct Node{
     38     int to,next;
     39     Node(){}
     40     Node(int a,int b):to(a),next(b){}
     41 }node[N<<1];
     42 
     43 inline void add(int x,int y){
     44     node[hcnt]=Node(y,head[x]);
     45     head[x]=hcnt++;
     46 }
     47 
     48 inline void init(){
     49     while(!sk.empty())sk.pop();
     50     mst(vis,0);
     51     mst(head,-1);
     52     mst(d,0);
     53     mst(dfn,0);
     54     hcnt=deep=0;
     55     block=leaf=0;
     56 }
     57 
     58 void dfs(int x,int fa){
     59     int flag=1;  ///这个不是必要的,有重边时有效
     60     sk.push(x);
     61     vis[x]=1;
     62     low[x]=dfn[x]=++deep;
     63     for(int i=head[x];~i;i=node[i].next){
     64         int e=node[i].to;
     65         if(e==fa&&flag){flag=0;continue;}
     66         if(vis[e])low[x]=min(low[x],dfn[e]);
     67         else if(!dfn[e]){
     68             dfs(e,x);
     69             low[x]=min(low[x],low[e]);
     70         }
     71     }
     72     if(low[x]==dfn[x]){
     73         ++block;    ///缩点
     74         int co;
     75         do{
     76             co=sk.top();sk.pop();
     77             vis[co]=0;
     78             color[co]=block;
     79         }while(co!=x);
     80     }
     81 }
     82 
     83 int main(){
     84     int i,j,group,Case=0,x,y;
     85     while(scanf("%d%d",&n,&m)!=EOF){
     86         init();
     87         for(i=0;i<m;++i){
     88             scanf("%d%d",&x,&y);
     89             add(x,y);
     90             add(y,x);
     91         }
     92         for(i=1;i<=n;++i){
     93             if(!dfn[i])dfs(i,-1);
     94         }
     95         if(block==1){printf("0
    ");continue;}   ///判断是否已经是双连通图
     96         for(i=1;i<=n;++i)
     97         for(j=head[i];~j;j=node[j].next){
     98             int e=node[j].to;
     99             if(color[i]!=color[e])
    100                 ++d[color[i]];   ///d数组保留的是缩点后每个点的度数
    101         }
    102         for(i=1;i<=block;++i){
    103             if(d[i]==0)leaf+=2;  ///如果有孤立的点,叶子节点加2
    104             else if(d[i]==1)++leaf;
    105         }
    106         printf("%d
    ",(leaf+1)/2);
    107     }
    108     return 0;
    109 }
  • 相关阅读:
    [LeetCode] 39. Combination Sum 组合之和
    CSS3
    常见中文字体在CSS中的Unicode编码(宋体:5B8B4F53)
    List<Object> 使用Linq
    查看工作流详情页面
    java程序调用.net接口服务地址的写法
    C# Repeater 嵌套
    JavaScript刷新页面,不重复提交
    Migration-添加表(加外键)
    Migration-添加表
  • 原文地址:https://www.cnblogs.com/Kurokey/p/5528489.html
Copyright © 2020-2023  润新知