hihocoder1183 连通性一·割边与割点

输入

第1行:2个正整数,N,M。表示点的数量N,边的数量M。1≤N≤20,000, 1≤M≤100,000

第2..M+1行:2个正整数,u,v。表示存在一条边(u,v),连接了u,v两台服务器。1≤u<v≤N

保证输入所有点之间至少有一条连通路径。

输出

第1行:若干整数,用空格隔开,表示满足要求的服务器编号。从小到大排列。若没有满足要求的点,该行输出Null

第2..k行:每行2个整数,(u,v)表示满足要求的边,u<v。所有边根据u的大小排序,u小的排在前,当u相同时,v小的排在前面。若没有满足要求的边,则不输出

/* ***********************************************
Author        :devil
Created Time  :2016/6/9 14:8:23
************************************************ */
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <cmath>
#include <stdlib.h>
using namespace std;
const int N=20010;
int dfn[N],low[N],f[N],cou=1;
vector<int>eg[N];
vector<int>point;
vector<pair<int,int> >edge;
void dfs(int u)
{
    bool add=0;
    int child=0;
    dfn[u]=low[u]=cou++;
    for(int i=0;i<eg[u].size();i++)
    {
        int v=eg[u][i];
        if(v==f[u]) continue;
        if(!dfn[v])
        {
            child++;
            f[v]=u;
            dfs(v);
            low[u]=min(low[u],low[v]);
            if(!add&&((!f[u]&&child>1)||(f[u]&&low[v]>=dfn[u])))
            {
                point.push_back(u);
                add=1;
            }
            if(low[v]>dfn[u]) edge.push_back(make_pair(min(u,v),max(u,v)));
        }
        else low[u]=min(low[u],dfn[v]);
    }
}
int main()
{
    //freopen("in.txt","r",stdin);
    int n,m,u,v;
    scanf("%d%d",&n,&m);
    for(int i=0;i<m;i++)
    {
        scanf("%d%d",&u,&v);
        eg[u].push_back(v);
        eg[v].push_back(u);
    }
    dfs(1);
    if(!point.size()) printf("Null\n");
    else
    {
        sort(point.begin(),point.end());
        printf("%d",point[0]);
        for(int i=1;i<point.size();i++)
            printf(" %d",point[i]);
        printf("\n");
    }
    sort(edge.begin(),edge.end());
    for(int i=0;i<edge.size();i++)
        printf("%d %d\n",edge[i].first,edge[i].second);
    return 0;
}
时间: 2024-10-12 18:36:11

hihocoder1183 连通性一·割边与割点的相关文章

hihoCoder 1183 连通性一&#183;割边与割点(Tarjan求割点与割边)

#1183 : 连通性一·割边与割点 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 还记得上次小Hi和小Ho学校被黑客攻击的事情么,那一次攻击最后造成了学校网络数据的丢失.为了避免再次出现这样的情况,学校决定对校园网络进行重新设计. 学校现在一共拥有N台服务器(编号1..N)以及M条连接,保证了任意两台服务器之间都能够通过连接直接或者间接的数据通讯. 当发生黑客攻击时,学校会立刻切断网络中的一条连接或是立刻关闭一台服务器,使得整个网络被隔离成两个独立的部分. 举个

hihoCoder_#1183_连通性一&#183;割边与割点

#1183 : 连通性一·割边与割点 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 还记得上次小Hi和小Ho学校被黑客攻击的事情么,那一次攻击最后造成了学校网络数据的丢失.为了避免再次出现这样的情况,学校决定对校园网络进行重新设计. 学校现在一共拥有N台服务器(编号1..N)以及M条连接,保证了任意两台服务器之间都能够通过连接直接或者间接的数据通讯. 当发生黑客攻击时,学校会立刻切断网络中的一条连接或是立刻关闭一台服务器,使得整个网络被隔离成两个独立的部分. 举个

HihoCoder 1183 : 连通性一&#183;割边与割点

连通性一·割边与割点 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 还记得上次小Hi和小Ho学校被黑客攻击的事情么,那一次攻击最后造成了学校网络数据的丢失.为了避免再次出现这样的情况,学校决定对校园网络进行重新设计. 学校现在一共拥有N台服务器(编号1..N)以及M条连接,保证了任意两台服务器之间都能够通过连接直接或者间接的数据通讯. 当发生黑客攻击时,学校会立刻切断网络中的一条连接或是立刻关闭一台服务器,使得整个网络被隔离成两个独立的部分. 举个例子,对于以下的

Tarjan的学习笔记 求割边求割点

博主图论比较弱,搜了模版也不会用... 所以决心学习以下tarjan算法. 割点和割边的概念不在赘述,tarjan能在线性时间复杂度内求出割边. 重要的概念:时间戟,就是一个全局变量clock记录访问结点的时间.一个无向图dfs会形成一个森林,当图只有一个连通分量时,就只有一棵树. 由于在无向图中,除了树边,其他都是反向边.可以画个图感受一下,可以反证的,如果有其他类型的边,那么dfs先沿着那些边跑图的,那么那些边就不存在. 如果结点是树根,那么它是割点的充要条件就是它有两个子结点. 定理 对于

tarjan,割边,桥,割点

这里是tarjan的基础知识, 求割点和割边 先来求割边, #include <cstdio> #include <iostream> #include <bits/stdc++.h> using namespace std; typedef long long ll; typedef unsigned long long ull; #define ls (t<<1) #define rs ((t<<1)|1) #define mid ((l+r

Tarjan系列1

tajan的dfs树系列算法: 求解割点,桥,强连通分量,点双联通分量,边双联通分量: tajan是一个dfs,把一个图变成一个dfs树结构, dfs树结构,本质是通过一个没有任何要求的dfs把图的边分为:树边和返祖边: 树边:dfs中父节点与其未曾遍历过的子节点间的边, 返祖边:父节点与他的dfs中曾作为该父节点祖先的子节点间的边 在有向图中,除了这二种边外,还有父节点与曾遍历过的子节点间的边,然而这个子节点不是父节点的祖先, 然而这种边在tarjan中没有意义,我们所求的东西用不上她们 伪代

Tarjan算法:求解图的割点与桥(割边)

简介: 割边和割点的定义仅限于无向图中.我们可以通过定义以蛮力方式求解出无向图的所有割点和割边,但这样的求解方式效率低.Tarjan提出了一种快速求解的方式,通过一次DFS就求解出图中所有的割点和割边. 欢迎探讨,如有错误敬请指正 如需转载,请注明出处 http://www.cnblogs.com/nullzx/ 1. 割点与桥(割边)的定义 在无向图中才有割边和割点的定义 割点:无向连通图中,去掉一个顶点及和它相邻的所有边,图中的连通分量数增加,则该顶点称为割点. 桥(割边):无向联通图中,去

图的割点与割边(超详细!!!)

·割点 割点概念,应该很好理解: 在一个无向图中,如果删除某个顶点,这个图就不再连通(任意两点之间无法相互到达),那么这个顶点就是这个图的割点. 举个例子: 图中的2号顶点就是割点, 删除2号后,4,5不通,1,6也不通等等 如何求割点? 很容易想到的方法是:依次删除每一个顶点,然后用dfs或者bfs来检查图是否依然连通.如果删除某个顶点后,导致图不再连通,那么刚才删除的顶点就是割点. 这种方法的时间复杂度是O(N(N+M)). 下面寻找复杂度低的方法来解决. 首先从图中任意节点开始dfs遍历上

{part1}DFN+LOW(tarjan)割点

什么是jarjan? 1)求割点 定义:在无向连通图中,如果去掉一个点/边,剩下的点之间不连通,那么这个点/边就被称为割点/边(或割顶/桥). 意义:由于割点和割边涉及到图的连通性,所以快速地求出割点和割边对于解决有关图连通性的问题有很大的帮助. 首先我们可以知道这个问题的上界为O(n*(n+m))/O(m*(n+m)),通过O(n)/O(m)枚举去掉的点/边,然后BFS在O(n+m)检查剩下的点的连通性就可以得到一个平方级别的算法. 这个算法显然难以进行优化,所以我们考虑从图本身的结构入手.