标签:
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 11684 | Accepted: 5422 |
Description
Input
Output
Sample Input
5 5 1 2 3 4 0 6 2 1 3 5 4 6 2 0 0
Sample Output
1 2
//tarjan算法求割点模板 #include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <cstring> #include <string> #include <algorithm> #include <stack> #include <queue> #include <vector> const int inf = 0x3f3f3f; const int MAXN = 1e2+10; using namespace std; vector<int> adj[MAXN]; int low[MAXN]; //能访问最先祖先结点位置 int dfn[MAXN]; //记录节点位置 int cur[MAXN]; //记录是否为割点 int rt,rt_sons; //根节点、根节点的子树数 int n; void init(){ rt_sons = 0; rt = 1; memset(low,0,sizeof(low)); memset(dfn,0,sizeof(dfn)); memset(cur,0,sizeof(cur)); for(int i=1;i<=n;i++) adj[i].clear(); } void dfs(int u,int degree){ dfn[u] = low[u] = degree; int v; for(int i=0;i<adj[u].size();i++){ v = adj[u][i]; if(!dfn[v]){ //后继结点没有被访问过,说明没有形成一个环 dfs(v,degree+1); if(u==rt)rt_sons++; else{ if(low[v]>=dfn[u]) //后继结点搜不到比该结点更早的结点,则说明该节点是割点 cur[u] = 1; low[u] = min(low[u],low[v]); //注意时刻更新结点的能搜索父节点的位置,后结点可能会形成一个环,搜索到比该结点更早的位置 } } else{ //后继结点已经访问过了,也就是回环的情况,能访问的位置必然更新 low[u] = min(low[u],dfn[v]); } } } int main() { int u,v; while(scanf("%d",&n),n){ init(); while(scanf("%d",&u),u){ while(getchar()!=‘\n‘){ scanf("%d",&v); adj[u].push_back(v); adj[v].push_back(u); } } dfs(rt,1); int sum=0; if(rt_sons>=2)cur[1] = 1; //y有两个子树的根是割点 for(int i=1;i<=n;i++){ if(cur[i])sum++; } /*cout<<"debug"<<endl; for(int i=1;i<=n;i++){ cout<<cur[i]<<" "; } cout<<endl; cout<<"debug"<<endl;*/ cout<<sum<<endl; } //cout << "Hello world!" << endl; return 0; }
标签:
原文地址:http://www.cnblogs.com/EdsonLin/p/5447763.html