D 华华和月月逛公园 (割边)

割边裸题

#include<bits/stdc++.h>
using namespace std;
#define pi acos(-1)
#define mod 80112002
#define ll long long
#define ull unsigned long long
#define mem(a) memset(a,0,sizeof(a))
#define cio ios::sync_with_stdio(false);
vector<int>e[100010]; // 建图
int dfn[100010]; // 时间戳
int low[100010]; // 追溯值(不经过父节点所能到的最小节点)
int n, m;
int cnt; // 割边数量
int step; // 搜索访问顺序

void tarjan(int x, int y)
{
    dfn[x] = low[x] = ++step; // 初始化时间戳以及追溯值
    for(int i = 0; i < e[x].size(); i++){ // 遍历相邻边
        int p = e[x][i]; // 节点p
        if(!dfn[p]){ // 未访问过节点p
            tarjan(p,x); // 继续搜索
            low[x] = min(low[x],low[p]); // 更新追溯值
            if(low[p]>dfn[x]) cnt++; // 判断是否为桥
        }else if(p!=y){ // 访问过的点并且不是x的父节点(y)
            low[x] = min(low[x],dfn[p]); 
        }
    }
}

int main()
{
    cnt = 0; 
    step = 0; // 初始化访问为0
    cin >> n >> m;
    int x, y;
    for(int i = 1; i <= m; i++){
        cin >> x >> y;
        e[x].push_back(y); // 无向图双向边
        e[y].push_back(x);
    }
    tarjan(1,0); // dfs搜索
    cout << m-cnt << endl;
    return 0;
}

 

posted @ 2020-07-12 20:32  古比  阅读(154)  评论(0编辑  收藏  举报