题目
AcWing 395. 冗余路径
Code
#include<cstring>
#include<cmath>
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=20010;
int n,m;
int h[maxn],cnt;
int dfn[maxn],low[maxn],vistime;
int stk[maxn],top;
int id[maxn],dcc_cnt;
bool is_bridge[maxn];
int d[maxn];
struct node{
int next,to,val;
}edg[maxn];
void add(int u, int v)
{
edg[cnt].to = v;
edg[cnt].next = h[u];
h[u]=cnt++;
}
inline int sread()
{
int x=0,f=1;char c=getchar();
while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();}
while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}
return f*x;
}
void tarjan(int u,int next)
{
dfn[u] = low[u] = ++ vistime;
stk[++top] = u;
for (int i = h[u]; i!=-1; i = edg[i].next)
{
int j = edg[i].to;
if (!dfn[j])
{
tarjan(j,i);
low[u]=min(low[u], low[j]);
if (dfn[u]<low[j])
is_bridge[i] = is_bridge[i^1] = true;
}
else if (i!=(next^1))
low[u]=min(low[u],dfn[j]);
}
if (dfn[u] == low[u])
{
++dcc_cnt;
int y;
do {
y=stk[top--];
id[y] = dcc_cnt;
}while (y!=u);
}
}
int main()
{
n=sread(); m=sread();
memset(h,-1,sizeof(h));
while(m--)
{
int a,b;
a=sread(); b=sread();
add(a,b), add(b,a);
}
tarjan(1,0);
for (int i=0;i<cnt;i++)
if (is_bridge[i])
d[id[edg[i].to]]++;
int cnt=0;
for(int i=1;i<=dcc_cnt;i++)
if(d[i]==1) cnt++;
printf("%d\n",(cnt+1)/2);
return 0;
}