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\n",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\n",i,ans);

110             }

111         }

112         if(sum==0)

113             printf("  No SPF nodes\n");

114         printf("\n");

115     }

116     return 0;

117 }
View Code

 

你可能感兴趣的:(poj)