POJ-1144 Tarjan求割点,双连通模板题
题意:给出一个无向图求割点数目。题目读入有点特殊,每一行开头给出ai,后面的bi都与ai连通。
总结:板子题。
// POJ-1144 #include<iostream> #include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring> #include<string> #include<cmath> #include<queue> #include<stack> #include<map> #include<bitset> #include<vector> #include<set> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define F(i,a,b) for (int i=a;i<b;i++) #define FF(i,a,b) for (int i=a;i<=b;i++) #define mes(a,b) memset(a,b,sizeof(a)) #define INF 0x3f3f3f3f typedef long long ll; const int N = 110; int n, tot, root; int head[N], cut[N], vis[N], dfn[N], low[N]; struct Edge{int to, next; }edge[N<<1]; void Init() { tot=0; mes(head, -1); mes(cut, 0); mes(vis, 0); } void Addedge(int u, int v) { edge[tot].to=v; edge[tot].next=head[u]; head[u]=tot++; } void Tarjan(int u, int fa) { int son=0; vis[u]=1; dfn[u]=low[u]=++tot; for(int e=head[u]; e!=-1; e=edge[e].next) { int v=edge[e].to; if(vis[v]==0) { Tarjan(v, u); son++; low[u]=min(low[u], low[v]); if((u==root && son>1) || (u!=root && dfn[u]<=low[v])) //如果u为树根且子树大于1;或者u不为树根,(u,v)为树枝边 cut[u]=1; } else if(vis[v]==1 && v!=fa) { low[u]=min(low[u], dfn[v]); } } vis[u]=2; } int main() { while(scanf("%d", &n) && n) { Init(); int u, v; while(scanf("%d", &u) && u) { while(getchar()!='\n') { //每一行以回车结束读入 scanf("%d", &v); Addedge(u, v); Addedge(v, u); } } root=1; Tarjan(root, -1); int ans=0; FF(i,1,n) if(cut[i]) ans++; printf("%d\n", ans); } return 0; }