POJ 2117 Electricity(割点)

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

题意:对于给出的无向图,删除某个顶点后,会得到多个连通分量。求最多的连通分量数(删除某点后)。

思路:DFS时统计每个点删掉后得到的连通块数cut[i]以及原图的连通块数t,则ans=max(t+cut[i])(0<=i<n)。

 #include <iostream>

 #include <cstdio>

 #include <cstring>

 #define max(x,y) ((x)>(y)?(x):(y))

 using namespace std;

 

 struct node

 {

     int v,next;

 };

 

 node edges[200005];

 int head[10005],e;

 int n,m;

 int dfn[10005],low[10005],cut[10005],ID;

 

 void Add(int u,int v)

 {

     edges[e].v=v;

     edges[e].next=head[u];

     head[u]=e++;

 }

 

 void DFS(int u,int pre,int root)

 {

     int i,v,sonNum=0;

     ID++;

     dfn[u]=low[u]=ID;

     for(i=head[u];i!=-1;i=edges[i].next)

     {

         v=edges[i].v;

         if(!dfn[v])

         {

             sonNum++;

             DFS(v,u,root);

             low[u]=min(low[u],low[v]);

             if(u==root&&sonNum>=2||u!=root&&dfn[u]<=low[v])

                cut[u]++;

         }

         else if(v!=pre)

         {

             low[u]=min(low[u],dfn[v]);

         }

     }

 }

 

 void deal()

 {

     memset(cut,0,sizeof(cut));

     memset(dfn,0,sizeof(dfn));

     ID=0;

     int i,ans=0,t=0;

     for(i=0;i<n;i++) if(!dfn[i]) t++,DFS(i,-1,i);

     for(i=0;i<n;i++) ans=max(ans,t+cut[i]);

     printf("%d\n",ans);

 }

 

 int main()

 {

     while(scanf("%d%d",&n,&m),n||m)

     {

         memset(head,-1,sizeof(head));

         e=0;

         int i,u,v;

         for(i=1;i<=m;i++)

         {

             scanf("%d%d",&u,&v);

             Add(u,v);

             Add(v,u);

         }

         if(m==0)

         {

             printf("%d\n",n-1);

             continue;

         }

         deal();

     }

     return 0;

 }

  

 

你可能感兴趣的:(poj)