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一下 连通性二·边的双连通分量

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

基于DFS求无向图的割点及桥(割边)算法总结 POJ_1144题解

1.割点,桥(割边)定义: 若v2(v1的后继节点)有且仅有反向边最远连接到v1,那么删除v1后不连通,v1是割点。作为一种特殊情况,如果v2及其后代通过反向边只能连回v2自己,那么只要删除edge...
  • zl_130
  • zl_130
  • 2015年08月13日 16:43
  • 150

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

/** 割点割边挺好理解的,割点就是一个无向连通图,把其中一个点 挖掉剩下的图不连通,割边就是把一条边砍掉不连通 比如:有一个通信网络,要求一颗炸弹,把这个通信网络搞得不连通...
  • zcube
  • zcube
  • 2015年09月05日 10:11
  • 2097

连通图的割点、割边(桥)、块、缩点

割点:删掉它之后(删掉所有跟它相连的边),图必然会分裂成两个或两个以上的子图。 块:没有割点的连通子图 割边:删掉一条边后,图必然会分裂成两个或两个以上的子图,又称桥。 缩点:把没有割边的连通子...

Tarjan算法求无向图割边割点、最近公共祖先的总结

无向图tarjan求割边割点、最近公共祖先总结 割点:删除这个点之后整个图变成不连通的两个部分的点 割点集合:在一个无向图中删除该集合中的所有点,能使原图变成互不相连的连通块的点的集合 点连通度...
  • MrH929
  • MrH929
  • 2016年07月19日 19:49
  • 1065

POJ 1523 SPF 割边与割点

本题要求出割点,并算出每个割点将图分成几个分支。 用tarjan算法求的割点,然后对每个割点,dfs求有多少个分支 每点的数是不一定的,我用的set存的点,vector存的图 求多少个分支就是:如果i...

无向连通图的割点与割边

无向连通图的割点与割边:最简单的方法:要判断一个点是否为割点,先把这个点和所有和它连接的边从图中去掉,再遍历下剩余的图,看看是否为连通的即可。这只在单独判断某一点(边)时才会选用。 割点将一个图分成了...

图的割点和割边

在一个无向连通图中,如果删除后某个顶点之后,图不再连通(即任意两点之间不能相互可达),这样的顶点叫做割点。 由此,删去某个顶点之后,然后进行一次dfs搜索一遍判断图是否还连通,便能求出该点是不是割点。...
  • yo_bc
  • yo_bc
  • 2017年03月07日 22:52
  • 501

割点、割边

定义: 无向图中,删除某个点(集)之后图不连通,该点即为割点(集); 无向图中,删除某个边(集)之后图不连通,该点即为割边(集)。   算法: dfs过程中,如果某个子树完全不与访问过的祖先...
  • swrdlgc
  • swrdlgc
  • 2012年02月29日 16:32
  • 336

割点、割边

一、割点、割边、双连通分支概念 挂接点(Articulation point)就是割点(Cut Vertex) 桥(Bridge)就是割边(Cut Edge) 割点:v为割点,则去掉v后...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:hiho一下 第五十二周(割边 割点)
举报原因:
原因补充:

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