沟槽的双连通
作者:
walili
,
2024-08-14 19:40:07
,
所有人可见
,
阅读 10
#include <bits/stdc++.h>
using namespace std;
using ll =long long;
const ll N=5010;
const ll M=10010;
int n, m, h[N], ne[M << 1], to[M << 1], ed , idx;
int dfn[N], low[N], bcc_id[N], bcc_cnt, stp;
bool bri[M << 1], vis[N];
vector<int> bcc[N];
void tar(int now, int fa) {
dfn[now] = low[now] = ++stp;
for (int i = h[now]; ~i; i = ne[i]) {
if (!dfn[to[i]]) {
tar(to[i], now);
low[now] = min(low[now], low[to[i]]);
if (low[to[i]] > dfn[now])
bri[i] = bri[i ^ 1] = 1;
}
else if (dfn[to[i]] < dfn[now] && to[i] != fa)
low[now] = min(low[now], dfn[to[i]]);
}
}
void DFS(int now) {
vis[now] = 1;
bcc_id[now] = bcc_cnt;
bcc[bcc_cnt].push_back(now);
for (int i = h[now]; ~i; i = ne[i]) {
if (bri[i]) continue;
if (!vis[to[i]]) DFS(to[i]);
}
}
void EBCC() {// clear dfn low bri bcc_id vis
bcc_cnt = stp = 0;
for (int i = 1; i <= n; ++i) if (!dfn[i]) tar(i, 0);
for (int i = 1; i <= n; ++i)
if (!vis[i]) ++bcc_cnt, DFS(i);
}
void add(ll u,ll v){
to[idx]=v;ne[idx]=h[u];h[u]=idx++;
}
int main(){
cin>>n>>m;
for(ll i=1;i<=n;i++) h[i]=-1;
for(ll i=1;i<=m;i++){
ll u,v;
cin>>u>>v;
add(u,v);
add(v,u);
}
EBCC();
ll cnt=0;
vector <ll> d(bcc_cnt+1);
for(ll u=1;u<=n;u++){
for(ll i=h[u];i!=-1;i=ne[i]){
ll v=to[i];
if(bcc_id[u]!=bcc_id[v]){
d[bcc_id[v]]++;
}
}
}
for(ll i=1;i<=bcc_cnt;i++){
// cout<<"id::"<<i<<"|||| ";
// for(auto t:bcc[i]) cout<<t<<' ';cout<<endl;
// cout<<"d::" <<d[i];
// cout<<endl;
cnt+=(d[i]==1);
}
cout<<(cnt+1)/2<<endl;
return 0;
}
瓦瓦棒棒喵
偷周杰板子