zoukankan      html  css  js  c++  java
  • Road Construction POJ

    Road Construction

     POJ - 3352 

    题意:一个无向图(无重边),问至少还要加多少边使得去掉任意一条边后任意两点仍可互达。

     无向图的边双连通分量(无重边)

    先用一次dfs标记出割边,然后dfs标记出各联通分量

    再根据割边,缩点重新建图,生成一颗树

    则答案就是(叶子树+1)/2.

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <algorithm>
     4 #include <cstring>
     5 using namespace std;
     6 const int maxv=1010;
     7 int n,m;
     8 struct Edge{
     9     int v,nex;
    10     bool iscut;
    11 }e[maxv<<1];
    12 int head[maxv];
    13 int cnt=0;
    14 void init(){
    15     memset(head,-1,sizeof(head));
    16     cnt=0;
    17 }
    18 void add(int u,int v){
    19     e[cnt].iscut=0;
    20     e[cnt].v=v;
    21     e[cnt].nex=head[u];
    22     head[u]=cnt++;
    23 }
    24 
    25 int pre[maxv],d[maxv],bccno[maxv],dfsk,bcc_cnt;
    26 bool vis[maxv];
    27 
    28 int dfs(int u,int f){
    29     int lowu=pre[u]=++dfsk;
    30     for(int i=head[u];i!=-1;i=e[i].nex){
    31         int v=e[i].v;
    32         if(!pre[v]){
    33             int lowv=dfs(v,u);
    34             lowu=min(lowv,lowu);
    35             if(lowv>pre[u]) e[i].iscut=e[i^1].iscut=true;
    36         }
    37         else if(pre[v]<pre[u]&&v!=f) lowu=min(lowu,pre[v]);  //反向边
    38     }
    39     return lowu;
    40 }
    41 void dfs1(int u){
    42     vis[u]=1;
    43     bccno[u]=bcc_cnt;
    44     for(int i=head[u];i!=-1;i=e[i].nex){
    45         if(e[i].iscut) continue;
    46         if(!vis[e[i].v]) dfs1(e[i].v);
    47     }
    48 }
    49 void find_bcc(int n){
    50     memset(pre,0,sizeof(pre));
    51     memset(bccno,0,sizeof(bccno));
    52     memset(vis,0,sizeof(vis));
    53     dfsk=bcc_cnt=0;
    54     for(int i=0;i<n;i++) if(!pre[i]) dfs(i,-1);
    55     for(int i=0;i<n;i++)
    56         if(!vis[i]) bcc_cnt++,dfs1(i);
    57 }
    58 
    59 int main(){
    60     while(scanf("%d%d",&n,&m)!=EOF){
    61         init();
    62         int u,v;
    63         for(int i=0;i<m;i++){
    64             scanf("%d%d",&u,&v);
    65             u--;v--;
    66             add(u,v);
    67             add(v,u);
    68         }
    69         find_bcc(n);
    70         memset(d,0,sizeof(d));
    71         for(int i=0;i<n;i++){
    72             for(int j=head[i];j!=-1;j=e[j].nex){
    73                 int v=e[j].v;
    74                 if(e[j].iscut) d[bccno[v]]++;
    75             }
    76         }
    77         int leaf=0;
    78         for(int i=1;i<=bcc_cnt;i++)
    79             if(d[i]==1) leaf++;
    80         printf("%d
    ",(leaf+1)/2);
    81     }
    82     return 0;
    83 }
    View Code
  • 相关阅读:
    图片灰度化,并且resize图片
    C语言学习笔记
    路飞学城14天集训营作业2—三级菜单
    路飞学城14天集训营作业4—员工信息表
    路飞学城14天集训营作业3—购物车
    路飞学城14天集训营作业1—登陆认证
    js钩子函数
    APP2.0后台控件API
    KindEditor 插件API使用说明
    TreeView插件 API
  • 原文地址:https://www.cnblogs.com/yijiull/p/7390275.html
Copyright © 2011-2022 走看看