割点
#include<bits/stdc++.h>
#define N 100005
using namespace std;
int n,cnt;
int hd[N],nxt[N<<1],to[N<<1],tot;
int dfn[N],low[N],now;
int ans[N];
void add(int a,int b)
{
to[++tot]=b;
nxt[tot]=hd[a];
hd[a]=tot;
}
void tarjan(int u,int fa)
{
dfn[u]=low[u]=++now;
for(int i=hd[u];i;i=nxt[i])
{
if(!dfn[to[i]])
{
tarjan(to[i],u);
low[u]=min(low[u],low[to[i]]);
}
else if(to[i]!=fa) low[u]=min(low[u],dfn[to[i]]);
}
if(fa==1) cnt++;
else if(low[u]>=dfn[fa]) ans[fa]=1;
}
int main()
{
scanf("%d",&n);
for(int x,y;scanf("%d",&x),x;)
{
while(scanf("%d",&y),y) add(x,y), add(y,x);
}
tarjan(1,0);
ans[1]=(cnt>1);
for(int i=1;i<=n;i++)
{
if(ans[i]) printf("%d ",i);
}
}
桥
#include<bits/stdc++.h>
#define N 100005
using namespace std;
int hd[N],nxt[N<<2],to[N<<2],tot;
int dfn[N],low[N],now;
int ans,f[N];
void add(int a,int b)
{
to[++tot]=b;
nxt[tot]=hd[a];
hd[a]=tot;
}
void tarjan(int u,int fa)
{
f[u]=fa;
dfn[u]=low[u]=++now;
for(int i=hd[u];i;i=nxt[i])
{
if(!dfn[to[i]])
{
tarjan(to[i],u);
low[u]=min(low[u],low[to[i]]);
}
else if(to[i]!=fa) low[u]=min(low[u],dfn[to[i]]);
}
// if(fa&&low[u]<dfn[fa]) ans++;//不能这么写
}
int main()
{
int n,m,x,y;
scanf("%d%d",&n,&m);
while(m--)
{
scanf("%d%d",&x,&y);
add(x,y), add(y,x);
}
tarjan(1,0);
for(int i=2;i<=n;i++)
{
if(low[i]>dfn[f[i]]) ans++;
}
printf("%d\n",ans);
}