输出各个重连通分量的边

输出各个重联通分量的边

#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <vector>
#include <set>
#include <stack>
#include <map>
#include <climits>

using namespace std;

#define LL long long
const int INF=0x3f3f3f3f;

const int N = 10101;
int n,m;

struct Edge
{
    int u,v,next;
    Edge() {}
    Edge(int _u,int _v)
    {
        u=_u,v=_v,next=0;
    }
    int cmp(Edge &t)
    {
        return (u==t.u&&v==t.v)||(u==t.v&&v==t.u);
    }
    void print()
    {
        printf("%d->%d ",u,v);
    }
} edge[N<<4];
int s[N],cnt;
int dfn[N],low[N],dep;
bool vis[N];
bool gao[N][N];
stack<Edge>S;

void AddEdge(int u,int v)
{
    edge[cnt].u=u;
    edge[cnt].v=v;
    edge[cnt].next=s[u];
    s[u]=cnt++;
}

void tarjan(int u,int pre)
{
    dfn[u]=low[u]=++dep;
    vis[u]=true;
    for(int i=s[u];~i;i=edge[i].next)
    {
        int v=edge[i].v;
        if(v==pre||gao[v][u]||gao[u][v]) continue;
        gao[v][u]=gao[u][v]=true;//这里要注意标记边.回边也只能走一次.
        S.push(Edge(u,v));
        if(!vis[v])
        {
            tarjan(v,u);
            low[u]=min(low[u],low[v]);
        }
        else low[u]=min(low[u],dfn[v]);//回边
        if(low[v]>=dfn[u])//删除顶点U,子节点V所在的子树将脱离.
        {
            Edge t=Edge(u,v);
            while(1)
            {
                Edge t1=S.top();
                S.pop();
                t1.print();
                if(t1.cmp(t)) break;
            }
            printf("\n");
        }
    }
}

int main()
{
    scanf("%d%d",&n,&m);
    {
        memset(s,-1,sizeof s);
        cnt=0;
        for(int i=0; i<m; i++)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            AddEdge(u,v);
            AddEdge(v,u);
        }
        memset(vis,0,sizeof vis);
        memset(gao,0,sizeof gao);
        dep=0;
        tarjan(1,0);
    }
    return 0;
}
7-7 图的连通性判断 分数 25 作者 陈越 单位 浙江大学 请编写程序,用广度优先搜索输出给定无向图中的各个连通分量,并判断给定的无向图是否连通。 注意输出顺序规定如下: 每个连通分量输出从其中编号最小的顶点开始; 不同连通分量按其第一个顶点的编号增序输出每个连通分量占一行; 当一个顶点有多个邻接点时,按其输入的逆序进行访问,即最后输入的邻接点,在广度优先搜索中应被最先访问输出。 输入格式: 输入首先在第一行给出图中最大顶点数量,即正整数 kMaxVertex(≤10)。 第二行给出两个正整数,依次为当前要创建的图的顶点数 n 和数 m(保证顶点数至少为 2 且不超过最大顶点数量)。 第三行给出 n 个英文字母,顺序对应每个顶点的信息。 随后 m 行,每行给出一条无向的两个端点的编号、以及的权顶点编号从 0 开始,权(≤2 30 )为整数。 同行数字、字符均以一个空格分隔。 输出格式: 按照题面中规定的顺序,输出图中的连通分量每个顶点的信息。每个连通分量占一行,字符间不要有空格。 随后,如果图不连通,则在一行中输出 有 x 个连通分量,其中 x 是连通分量的个数。 最后一行输出 该图连通性为 y,其中图连通时 y 值为 1,否则为 0。 输入样例: 10 6 7 a b c d e f 2 0 2 2 3 1 3 0 3 3 4 4 2 4 2 4 0 5 4 5 1 输出样例: aedcf b 有 2 个连通分量 该图连通性为 0
最新发布
04-28
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值