hdu 3849(双联通求桥)

本文介绍了一种用于检测图中割边的算法实现。通过深度优先搜索(DFS)方法,文章详细阐述了如何识别图中连接点的重要路径,并特别注意处理不连通图的情况。此外,还提供了一个具体示例,展示了从字符串输入到最终输出割边的完整过程。

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

题目意思:
给你n,m表示一个图的n个点,m条边。   下面m行为  x ,y即x和y之间有条边,求割边,2个坑点:若图不连通输出0;若有多条割边按输入先后顺序输出,而且x,y顺序也和输入时一致   


#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
using namespace std;
#define N 10005

struct node{
    int x, y, id, id1, id2;
}ans[N];

struct mem{
    int y, id, id1, id2;
};

vector<mem>ve[N];
map<string,int>ma;
map<int,string>mb;
int low[N], dfn[N];
int visited[N];
int n, m, dfn_clock;
int nu;

void init(){
    for(int i=0;i<=n;i++) ve[i].clear();
    ma.clear();mb.clear();
    memset(dfn,-1,sizeof(dfn));
    memset(visited,0,sizeof(visited));
}

void dfs(int u,int fa){
    int i, j, k, v;
    node p;
    mem q;
    //printf("1111111111\n");
    low[u]=dfn[u]=dfn_clock++;
    
    visited[u]=1;
    for(i=0;i<ve[u].size();i++){
        q=ve[u][i];
        if(q.y==fa) continue;
    //    printf("%d\n",v);
        if(!visited[q.y]){
            dfs(q.y,u);
            low[u]=min(low[u],low[q.y]);
            if(low[q.y]>dfn[u]) {
                p.x=u;p.y=q.y;p.id=q.id;p.id1=q.id1;p.id2=q.id2;
                ans[nu++]=p;
            }
        }
        else low[u]=min(low[u],dfn[q.y]);
        
    }
}

bool cmp(node a,node b){
    return a.id<b.id;
}

main()
{
    int t, i, j, k, id;
    char s1[200], s2[200];
    mem p;
    cin>>t;
    while(t--){
        scanf("%d %d",&n,&m);
        init();k=1;id=1;
        while(m--){
            scanf("%s%s",s1,s2);
            if(ma[s1]==0) ma[s1]=k,mb[k]=s1,++k;
            if(ma[s2]==0) ma[s2]=k,mb[k]=s2,++k;
            int x=ma[s1], y=ma[s2];
            p.y=ma[s2];p.id=id++;p.id1=1;p.id2=2;
            ve[x].push_back(p);
            p.y=ma[s1];p.id=id++;p.id1=2;p.id2=1;
            ve[y].push_back(p);
        }
    
        dfn_clock=nu=0;
         dfs(1,-1);
         int f=1;
        for(i=1;i<=n;i++) {
            if(dfn[i]==-1){
            break;
            }
        }
        if(i<=n){
            printf("0\n");continue;
        }
        sort(ans,ans+nu,cmp);
        printf("%d\n",nu);
        for(i=0;i<nu;i++){
            if(ans[i].id1<ans[i].id2)
            cout<<mb[ans[i].x]<<" "<<mb[ans[i].y]<<endl;
            else cout<<mb[ans[i].y]<<" "<<mb[ans[i].x]<<endl;
        }
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值