zoukankan      html  css  js  c++  java
  • POJ 3177 Redundant Paths 无向图边双联通基础题

    题意:

    给一个无向图,保证任意两个点之间有两条完全不相同的路径

    求至少加多少边才能实现


    题解:

    得先学会一波tarjan无向图

    桥的定义是:删除这条边之后该图不联通

    一条无向边(u,v)是桥,当且仅当(u,v)为树枝边,且满足 DFN(u)<Low(v).(因为 v 想要到
    达 u 的父亲必须经过(u,v)这条边,所以删去这条边,图不连通)

    先用Tarjan无向图缩边双联通分量,这样原图就构成了一颗树,

    对于树的叶子节点来说,显然他们需要连边,可以证明的是,我们连至多(叶子节点个数+1)/2的边就可以完成加边(叶子节点两两相连)

    所以答案就是(叶子节点个数+1)/2

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 #define N 5010
     5 #define M 10100
     6 using namespace std;
     7 int head[N],cut[M],n,m,ecnt=2,u,v,dfn[N],low[N],indx,fa[N],du[N],ans;
     8 struct edge
     9 {
    10     int u,v,nxt;
    11 }e[M*2];
    12 inline int find(int x)
    13 {
    14     return fa[x]=fa[x]==x?x:find(fa[x]);
    15 }
    16 void add(int u,int v)
    17 {
    18     e[ecnt].v=v;
    19     e[ecnt].nxt=head[u];
    20     e[ecnt].u=u;
    21     head[u]=ecnt++;
    22     e[ecnt].v=u;
    23     e[ecnt].nxt=head[v];
    24     e[ecnt].u=v;
    25     head[v]=ecnt++;
    26 }
    27 void dfs(int u,int E)
    28 {
    29     dfn[u]=low[u]=++indx;
    30     for (int i=head[u];i;i=e[i].nxt)
    31     {
    32     if (i==(E^1)) continue;
    33     int v=e[i].v;
    34     if (!dfn[v])
    35     {
    36         dfs(v,i);
    37         if (low[v]<low[u]) low[u]=low[v];
    38         if (low[v]>dfn[u]) cut[i]=cut[i^1]=1;
    39     }
    40     else
    41         if (dfn[v]<low[u])
    42         low[u]=dfn[v];
    43     }
    44 }
    45 int main()
    46 {
    47     scanf("%d%d",&n,&m);
    48     for (int i=1;i<=m;i++)
    49     {
    50     scanf("%d%d",&u,&v);
    51     add(u,v);
    52     }
    53     dfs(1,-1);
    54     for (int i=1;i<=n;i++)
    55     fa[i]=i;
    56     for (int i=2;i<ecnt;i+=2)
    57     if (!cut[i]) fa[find(e[i].u)]=find(e[i].v);
    58     for (int i=2;i<ecnt;i+=2)
    59     if (cut[i]) du[find(e[i].u)]++,du[find(e[i].v)]++;
    60     for (int i=1;i<=n;i++)
    61     if (find(i)==i && du[i]==1) ans++;
    62     printf("%d",(ans+1)/2);
    63     return 0;
    64 }
  • 相关阅读:
    封装( 增删改 查 )类
    php注释规范
    php访问mysql数据库
    php 文件限速下载代码
    jQuery鼠标事件汇总
    权限管理
    文件管理 打开-返回上级
    文件操作
    简单的文件上传
    ajax XML
  • 原文地址:https://www.cnblogs.com/mrsheep/p/7845247.html
Copyright © 2011-2022 走看看