hiho一下 第五十二周(割边 割点)

原创 2015年07月10日 16:02:58

最近做到了割边割点的东西。就把这几天学到的写下来。

在一个无向图中。

割点:就是删除了这个点,图会不在连通或者连通分量增加。

割边:删除一条边,图会不在连通或者连通分量增加。


做割点时候,会用到两个数组。low[],dfn[]、

low[]数组保存的可以回到祖先的最小节点。
dfn[]数组保存的是当前节点的序列号,可能和题目给出的序列号不是一个数字,要看走的顺序。


然后又由于删除一个点后,当这个点是割点之后,那么这个点的子节点就不会返回到之前的祖先。


当U指向V

low[now]=min(low[now],dfn[v]);当遇到返祖边的时候

low[now]=min(low[now],low[v]);


割点的判断if(child>1&&now==1||now!=1&&low[v]>=dfn[now])

当他的low[]的子节点大于等于他的话。则说明这个点是他的祖先。

假如这个点不是起点的话, 一定是这个图的割点。将这个分割开的点。

假如是起点话,需要两个以上的子树。


以hiho一下 第五十二周 的题目为例。点击打开链接

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int maxn=1000001;
const int INF=1<<29;
int n,m,sum;
int e,cnt[maxn],kk=0;;
int head[maxn],nxt[maxn],pnt[maxn];
int low[maxn],dfn[maxn],vis[maxn];
//low[]数组保存的可以回到祖先的最小节点。
//dfn[]数组保存的是当前节点的序列号,可能和题目给出的序列号不是一个数字,要看走的顺序。
int aa[maxn],ck=0;
struct node
{
    int x,y;
}num[maxn];
int cmp(node p1,node p2)
{
    if(p1.x==p2.x) return p1.y<p2.y;
    return p1.x<p2.x;
}
void AddEdge(int u,int v)
{
    pnt[e]=v;nxt[e]=head[u];head[u]=e++;
}

void dfs(int now,int father,int dfnth)
{
    low[now]=dfn[now]=dfnth;
    vis[now]=1;
    int child=0;
    //printf("==%d %d %d\n",now,father,dfnth);
    for(int i=head[now];i!=-1;i=nxt[i])
    {
        if(pnt[i]!=father&&vis[pnt[i]]==1){//遇到返祖边的时候,就更新low[]值
               // printf("!!%d %d %d %d\n",now,pnt[i],father,dfn[pnt[i]]);

            low[now]=min(low[now],dfn[pnt[i]]);
        }
        if(!vis[pnt[i]])
        {
            dfs(pnt[i],now,dfnth+1);
            child++;
            low[now]=min(low[now],low[pnt[i]]);
            if(low[pnt[i]]>dfn[now])//割边
            {
                num[kk].x=min(now,pnt[i]);
                num[kk++].y=max(now,pnt[i]);

            }
             if(child>1&&now==1||now!=1&&low[pnt[i]]>=dfn[now])//割点,
            {
                cnt[now]=1;
                sum++;
            }
        }
    }

    vis[now]=2;
}
int main()
{
    scanf("%d%d",&n,&m);
    e=0;
    sum=0;
    memset(head,-1,sizeof(head));
    memset(dfn,0,sizeof(dfn));
    memset(vis,0,sizeof(vis));
    memset(cnt,0,sizeof(cnt));
    int u,v;
    for(int i=0;i<m;i++)
    {
        scanf("%d%d",&u,&v);
        AddEdge(u,v);
        AddEdge(v,u);
    }
    if(n==2)
    {
        puts("NULL");
        puts("1 2");
        return 0;
    }
    dfs(1,-1,1);
    for(int i=1;i<=n;i++)
        printf("%d ",low[i]);puts("");
    for(int i=1;i<=n;i++)
        printf("%d ",dfn[i]);puts("");
    if(sum!=0)
    {
        for(int i=1; i<=n; i++)
            if(cnt[i])aa[ck++]=i;
        for(int i=0; i<ck; i++)
            printf("%d%c",aa[i],i==ck-1?'\n':' ');
    }
    else
        puts("Null");
    if(kk!=0)
    {
        sort(num,num+kk,cmp);
        printf("%d %d\n",num[0].x,num[0].y);
        for(int i=1; i<kk; i++)
            if(num[i-1].x!=num[i].x||num[i-1].y!=num[i].y)
                printf("%d %d\n",num[i].x,num[i].y);
    }

    return 0;
}
/*
6 7
1 2
2 3
3 1
2 4
4 5
5 6
6 4

8 12
1 2
2 3
2 1
2 4
3 2
3 4
4 2
4 3
4 5
5 4
8 7
7 8

6 8
2 5
1 2
2 3
3 1
3 4
4 5
5 6
6 4

7 7
1 2
2 3
3 4
2 5
4 5
5 6
5 7
*/



版权声明:本文为博主原创文章,未经博主允许不得转载。

hiho一下 第五十八周

题意分析给定字符串S,判定S是否存在子串S’满足”aa…abb…bcc…c”的形式。其中abc为连续的三个字母,且a,b,c的数量相同。原题目中数量相等的连续n(n>3)个字母也是可行的,而实际上当n...
  • kl28978113
  • kl28978113
  • 2015年09月28日 23:41
  • 1293

hiho一下 第六十五周

题意分析给定一条单行道的高速公路,汽车都是从坐标0,向坐标无穷移动。又因为是单行道,所以后面的车无法超越前面的车。在时刻0时,有 N 辆车同时进入这条单行道,第i辆车从坐标x[i]进入,并且将会从坐标...
  • kl28978113
  • kl28978113
  • 2015年10月10日 15:21
  • 1278

hiho一下 第五十九周

题意分析给定一个单线程程序运行的记录,包含有每个函数启动和结束的时间。判定该份记录是否错误,主要的错误包含: 记录中的时间不是严格递增的 一个函数的结束时间比启动时间更早 记录中一个函数有不对应的启动...
  • kl28978113
  • kl28978113
  • 2015年09月28日 23:49
  • 1244

图论判别图G是否为割点割边

  • 2017年12月20日 09:39
  • 1.02MB
  • 下载

hiho一下 连通性二·边的双连通分量

时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 在基本的网络搭建完成后,学校为了方便管理还需要对所有的服务器进行编组,网络所的老师找到...
  • u014634338
  • u014634338
  • 2015年07月10日 17:33
  • 861

poj Transferring Sylla(如何快速的判断一个图是否是3—连通图,求割点,割边)

Transferring Sylla   首先,什么是k连通图?k连通图就是指至少去掉k个点使之不连通的图。 题目:    题目描述的很裸,就是给你一张图要求你判断这图是否是3-连通图。 ...
  • u010016150
  • u010016150
  • 2014年10月03日 17:15
  • 1166

图论算法(五)--求解割点、割边(JAVA)

割点:对于一个连通图来说,如果删除某个点之后图不再连通,这个点就称为割点 割点算法 时间复杂度:O(N+M) 但是下面给出的算法时间复杂度为O(N^2),这是因为下面的存储结构都是邻接矩阵,这样...
  • qq_39630587
  • qq_39630587
  • 2018年01月12日 22:45
  • 5

【学习笔记】图论 割点 割边

图论 割点 割边(讲解+模板)
  • lhq_er
  • lhq_er
  • 2017年07月16日 16:24
  • 257

割点割边连通分量等连通性相关算法

=w=为什么要摘要
  • DKFleet
  • DKFleet
  • 2015年02月18日 17:45
  • 217

用Tarjan算法求无向连通图割点&&割边

/** 割点割边挺好理解的,割点就是一个无向连通图,把其中一个点 挖掉剩下的图不连通,割边就是把一条边砍掉不连通 比如:有一个通信网络,要求一颗炸弹,把这个通信网络搞得不连通...
  • zcube
  • zcube
  • 2015年09月05日 10:11
  • 2333
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:hiho一下 第五十二周(割边 割点)
举报原因:
原因补充:

(最多只允许输入30个字)