http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=311
割点算法
《算法与艺术信息学竞赛》P285
建立在DFS的基础上
#include<iostream> #include<cstring> #include<vector> #include<algorithm> #include<stdio.h> #include<string> #include<sstream> using namespace std; int n,m,k,ans,d[101],ancestor[101],c[101],cut[101]; vector <int> adj[101]; void DFS(int k,int fa,int deep) { int tot; c[k]=-1; d[k]=deep; ancestor[k]=deep,tot=0; for(int i=0;i<adj[k].size();i++) { int w=adj[k][i]; if(w!=fa&&c[w]==-1)ancestor[k]=min( ancestor[k], d[w] ); else if(c[w]==0) { DFS(w,k,deep+1); tot++,ancestor[k]=min(ancestor[k],ancestor[w]); if(fa==-1&&tot>1||fa!=-1&&ancestor[w]>=d[k]) cut[k]=1; } } c[k]=1; } int main() { string s; while(cin>>n&&n) { for(int i=1;i<=n;i++) adj[i].clear(); while(getline(cin,s)&&s!="0") { istringstream sin(s); sin>>m; if(m) { while(sin>>k) { adj[k].push_back(m); adj[m].push_back(k); } } } memset(d,0,sizeof(d)); memset(c,0,sizeof(c)); memset(cut,0,sizeof(cut)); memset(ancestor,0,sizeof(ancestor)); ans=0; for(int i=1;i<=n;i++) { if(!c[i])DFS(i,-1,0); } for(int i=1;i<=n;i++) if(cut[i])ans++; printf("%d\n",ans); } }