#1183 : 连通性一·割边与割点

本文探讨了在校园网络设计中如何利用割点和割边确保网络在遭受黑客攻击时能迅速隔离成两个独立部分,以防止数据丢失。举例说明了割边(如(3,4))和割点(如服务器3)在断开网络连接中的作用,阐述了寻找这些关键元素的方法。" 113441714,10542878,MySQL高级:视图、存储过程与函数详解,"['数据库', 'MySQL', '视图', '存储过程', '函数']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

描述

还记得上次小Hi和小Ho学校被黑客攻击的事情么,那一次攻击最后造成了学校网络数据的丢失。为了避免再次出现这样的情况,学校决定对校园网络进行重新设计。

学校现在一共拥有N台服务器(编号1..N)以及M条连接,保证了任意两台服务器之间都能够通过连接直接或者间接的数据通讯。

当发生黑客攻击时,学校会立刻切断网络中的一条连接或是立刻关闭一台服务器,使得整个网络被隔离成两个独立的部分。

举个例子,对于以下的网络:

每两个点之间至少有一条路径连通,当切断边(3,4)的时候,可以发现,整个网络被隔离为{1,2,3},{4,5,6}两个部分:

若关闭服务器3,则整个网络被隔离为{1,2},{4,5,6}两个部分:

小Hi和小Ho想要知道,在学校的网络中有哪些连接和哪些点被关闭后,能够使得整个网络被隔离为两个部分。

在上面的例子中,满足条件的有边(3,4),点3和点4。

 

提示:割边&割点

 
输入

第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小的排在前面。若没有满足要求的边,则不输出



样例输入
6 7
1 2
1 3
2 3
3 4
4 5
4 6
5 6
样例输出
3 4
3 4

模板模板。控制好输出。

代码:

#include<bits/stdc++.h>

using namespace std;
const int maxn=20000+10;
int n,m;
int dfs_clock;
vector<int> G[maxn];
int pre[maxn],low[maxn];
bool iscut[maxn];
struct poin
{
    int l,r;
}q[maxn];
int bi;
bool cmp(poin a,poin b)
{
    if(a.l<b.l)return 1;
    else if(a.l==b.l)
    {
        if(a.r<b.r)return 1;
        else return 0;
    }
    else return 0;
}
int dfs(int u,int fa)
{
    int lowu=pre[u]=++dfs_clock;
    int child=0;
    for(int i=0; i<G[u].size(); i++)
    {
        int v=G[u][i];
        if(!pre[v])
        {
            child++;
            int lowv=dfs(v,u);
            lowu=min(lowu,lowv);
            if(lowv>=pre[u])
            {
                iscut[u]=true;
                if(lowv>pre[u])
                {
                    q[bi].l=min(u,v);
                    q[bi++].r=max(u,v);
                }

            }
        }
        else if(pre[v]<pre[u] && v!=fa)
        {
            lowu=min(lowu,pre[v]);
        }
    }
    if(fa<0 && (child==1||child==0) )
        iscut[u]=false;
    return low[u]=lowu;
}

int main()
{
    while(scanf("%d%d",&n,&m)==2&&n)
    {
        dfs_clock=0;
        bi=0;
        memset(pre,0,sizeof(pre));
        memset(iscut,0,sizeof(iscut));
        for(int i=0;i<n;i++) G[i].clear();
        for(int i=0;i<m;i++)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            G[u].push_back(v);
            G[v].push_back(u);
        }
        dfs(1,-1);
        sort(q,q+bi,cmp);
        int f=0;
        for(int i=1;i<=n;i++)if(iscut[i]==true)
        {
            printf("%d ",i);f=1;
        }
            if(!f)printf("Null\n");
            else printf("\n");
            for(int i=0;i<bi;i++)
            {
                printf("%d %d\n",q[i].l,q[i].r);
            }
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值