题意:
给了一个无向图..问有多少个割点...
题解:
发现tarjan这一块还有一个地方没搞~~补上...
用tarjan找双联通分量...若有条边其起点的dfn不大于终点的low ..那么起点"可能"是割点...之所以说可能是因为每次dfs的第一个点必定会多一次dfn大于low的边...所以每次进入了dfs回来后要将起点的记录值-1..若其还是大于0的才说明该点是割点...
Program:
#include<iostream> #include<stdio.h> #include<string.h> #include<set> #include <stack> #include<queue> #include<algorithm> #include<cmath> #define oo 1000000007 #define ll long long #define pi acos(-1.0) #define MAXN 205 #define MAXM 50505 using namespace std; struct node { int v,id,next; }edge[MAXM]; int Ne,_next[MAXN],P[MAXN],dfn[MAXN],low[MAXN],DfsIndex; void addedge(int u,int v,int id) { edge[++Ne].next=_next[u],_next[u]=Ne; edge[Ne].v=v,edge[Ne].id=id; } void tarjan(int u,int id) { dfn[u]=low[u]=++DfsIndex; for (int k=_next[u];k;k=edge[k].next) if (edge[k].id!=id) { int v=edge[k].v; if (!dfn[v]) { tarjan(v,edge[k].id); low[u]=min(low[u],low[v]); if (dfn[u]<=low[v]) P[u]++; }else low[u]=min(low[u],dfn[v]); } } int main() { int n,u,v,id,ans; char c; while (~scanf("%d",&n) && n) { Ne=id=0,memset(_next,0,sizeof(_next)); while (~scanf("%d",&u) && u) while (scanf("%c",&c) && c!='\n') scanf("%d",&v),addedge(u,v,++id),addedge(v,u,id); memset(P,0,sizeof(P)); memset(dfn,0,sizeof(dfn)); DfsIndex=0; for (u=1;u<=n;u++) if (!dfn[u]) { tarjan(u,0); P[u]--; } ans=0; for (u=1;u<=n;u++) ans+=!(!P[u]); printf("%d\n",ans); } return 0; }