求割点(无向边):
所谓的割点,就是删除某个点,图便不连通了。
POJ 1523
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; const int MN=1111; struct Edge { int to,next; }edge[MN<<2]; int dfn[MN]; int low[MN]; int head[MN<<2]; int subnet[MN]; int E,tp,root; int vis[MN]; void Init() { memset(dfn,-1,sizeof(dfn)); memset(low,0,sizeof(low)); memset(head,-1,sizeof(head)); memset(subnet,0,sizeof(subnet)); memset(vis,0,sizeof(vis)); E=tp=0; } void Add(int a,int b) { edge[E].to=b; edge[E].next=head[a]; head[a]=E++; } void tarjan(int u,int fa) { int son=0; vis[u]=1; dfn[u]=low[u]=++tp; for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].to; if(vis[v]==1 && v!=fa) low[u]=min(low[u],dfn[v]); if(!vis[v]) { tarjan(v,u); son++; low[u]=min(low[u],low[v]); if((u==root && son>1) || (u!=root)&& dfn[u]<=low[v]) subnet[u]++; } } vis[u]=2; } int main() { int i,cas=1,n,a,b,nodes; while(scanf("%d",&n) && n) { nodes=n; Init(); scanf("%d",&b); Add(n,b); Add(b,n); while(scanf("%d",&a) && a) { scanf("%d",&b); if(nodes<a) nodes=a; if(nodes<b) nodes=b; Add(a,b); Add(b,a); } for(i=1;i<=nodes;i++) { if(dfn[i]==-1) { root=i; tarjan(i,-1); } } int flag=0; printf("Network #%d\n",cas++); for(i=1;i<=nodes;i++) { if(subnet[i]>=1) { flag=1; printf(" SPF node %d leaves %d subnets\n",i,subnet[i]+1); } } if(flag==0) printf(" No SPF nodes\n"); puts(""); } }