poj 1523 SPF(双连通分量割点模板)

题目链接:http://poj.org/problem?id=1523

题意:给出无向图的若干条边,求割点以及各个删掉其中一个割点后将图分为几块。

题目分析:割点用tarjan算法求出来,对于每个割点,dfs一次图,求出有几块不连通的子图。

AC代码:

  1 #include<cstdio>
  2 #include<cstring>
  3 const int N=1000+5;
  4 struct EDGE{
  5     int v,next;
  6 }edge[N*N/2];
  7 int first[N],low[N],dfn[N],cut[N],vis[N];
  8 int g,ans,rt,son,cnt,sum;
  9 int min(int a,int b)
 10 {
 11     return a<b?a:b;
 12 }
 13 int max(int a,int b)
 14 {
 15     return a>b?a:b;
 16 }
 17 void AddEdge(int u,int v)
 18 {
 19     edge[g].v=v;
 20     edge[g].next=first[u];
 21     first[u]=g++;
 22 }
 23 void Tarjan(int u)
 24 {
 25     int i,v;
 26     low[u]=dfn[u]=++cnt;
 27     for(i=first[u];i!=-1;i=edge[i].next)
 28     {
 29         v=edge[i].v;
 30         if(!dfn[v])
 31         {
 32             Tarjan(v);
 33             low[u]=min(low[u],low[v]);
 34             if(u==rt)
 35                 son++;
 36             else
 37             {
 38                 if(low[v]>=dfn[u])
 39                     cut[u]=true;
 40             }
 41         }
 42         else
 43             low[u]=min(low[u],dfn[v]);
 44     }
 45 }
 46 void dfs(int u)
 47 {
 48     vis[u]=1;
 49     for(int i=first[u];i!=-1;i=edge[i].next)
 50     {
 51         int v=edge[i].v;
 52         if(!vis[v])
 53             dfs(v);
 54     }
 55 }
 56 int main()
 57 {
 58     int t=0,u,v,n,i,p;
 59     while(scanf("%d",&u)&&u)
 60     {
 61         t++;
 62         n=-1;
 63         memset(first,-1,sizeof(first));
 64         memset(cut,false,sizeof(cut));
 65         memset(dfn,0,sizeof(dfn));
 66         g=cnt=sum=0;
 67         n=max(n,u);
 68         scanf("%d",&v);
 69         n=max(n,v);
 70         AddEdge(u,v);
 71         AddEdge(v,u);
 72         while(scanf("%d",&u)&&u)
 73         {
 74             scanf("%d",&v);
 75             n=max(n,u);
 76             n=max(n,v);
 77             AddEdge(u,v);
 78             AddEdge(v,u);
 79         }
 80         for(i=1;i<=n;i++)
 81         {
 82             if(!dfn[i])
 83             {
 84                 rt=i;
 85                 son=0;
 86                 Tarjan(i);
 87                 if(son>1)
 88                     cut[rt]=true;
 89             }
 90         }
 91         printf("Network #%d
",t);
 92         for(i=1;i<=n;i++)
 93         {
 94             if(cut[i])
 95             {
 96                 sum++;
 97                 ans=0;
 98                 memset(vis,0,sizeof(vis));
 99                 vis[i]=1;
100                 for(p=first[i];p!=-1;p=edge[p].next)
101                 {
102                     v=edge[p].v;
103                     if(!vis[v])
104                     {
105                         dfs(v);
106                         ans++;
107                     }
108                 }
109                 printf("  SPF node %d leaves %d subnets
",i,ans);
110             }
111         }
112         if(sum==0)
113             printf("  No SPF nodes
");
114         printf("
");
115     }
116     return 0;
117 }
View Code
原文地址:https://www.cnblogs.com/frog112111/p/3328694.html