题意:
给定n个点 m条边的无向图(点标从0开始)
问:
去掉一个点,使得最终图的连通分量数最大
输出最大的连通分量数
思路:
求出所有割点(当且仅当删掉的点为割点时,连通分量数会增加)
注意:若图中没有边时(m==0) 全都是孤立点,则删点后连通分量数会减少( ans= n-1)
图中存在重边自环等各种坑爹的东西
#include<stdio.h> #include<string.h> #include<vector> #include<iostream> #include<queue> #include<stack> #include<set> using namespace std; int n, m;//n个点 m条无向边 #define N 20100 #define M 1000006 //点标从0开始 int head[N],edgenum; int low[N],dfn[N],Stack[N<<1],instack[N],add_block[N],indexx,top,iscut[N], block_cnt; //block_cnt为图的连通分量数 struct node { int to,next; }edge[M]; void add(int u,int v) { edge[edgenum].to=v; edge[edgenum].next=head[u]; head[u]=edgenum++; } void tarjin(int u,int pre) { int i,v; low[u]=dfn[u]=++indexx; Stack[top++]=u; int son=0; for(i=head[u];i!=-1;i=edge[i].next) { v=edge[i].to; if(v==pre)continue; if(!dfn[v]) { son++; tarjin(v,u); if(low[u]>low[v])low[u]=low[v]; if(u!=pre&&low[v]>=dfn[u]) { iscut[u]=1; add_block[u]++; } } else if(low[u]>dfn[v])low[u]=dfn[v]; } if(u==pre)add_block[u]=son-1; if(u==pre&&son>1)iscut[u]=1; //top--; } void find_bcc(int n){ memset(dfn,0,sizeof(dfn)); memset(instack,0,sizeof(instack)); memset(add_block,0,sizeof(add_block)); memset(iscut,0,sizeof(iscut)); indexx=top=0; block_cnt=0; //连通分量数 for(int i=0;i<n;i++)if(!dfn[i])tarjin(i,i),block_cnt++; } int main(){ int u, v; while(scanf("%d%d",&n,&m),n+m){ if(m==0){printf("%d\n", n-1);continue;} memset(head, -1, sizeof(head)); edgenum = 0; int dou = 0; for(int i = 0; i < m; i++){ scanf("%d %d",&u,&v); if(u==v){dou++;continue;} add(u,v), add(v,u); } if(dou == m){printf("%d\n", n-1);continue;} find_bcc(n); int Maxn = block_cnt; for(int i = 0; i < n; i++)if(iscut[i])Maxn = max(Maxn, block_cnt+add_block[i]); printf("%d\n", Maxn); } return 0; } /* 7 7 1 2 1 3 2 4 3 4 4 5 4 6 5 6 7 8 1 2 1 3 2 4 3 4 4 5 4 6 5 6 0 1 7 8 1 2 1 3 2 4 3 4 4 5 4 6 5 6 0 4 3 3 0 1 0 2 2 1 4 2 0 1 2 3 3 1 1 0 5 4 1 2 1 2 1 2 2 1 50 14 1 5 3 6 1 5 5 3 3 4 3 6 0 5 43 8 9 5 30 8 6 7 10 12 19 8 6 42 8 8 1 2 1 3 2 4 3 4 4 5 4 6 5 6 4 7 6 5 0 1 1 2 1 3 1 4 1 5 10 7 0 1 1 2 1 3 1 4 1 5 0 4 4 3 10 9 0 1 1 2 1 3 1 4 1 5 0 4 4 3 3 2 2 5 10 10 0 1 1 2 1 3 1 4 1 5 0 4 4 3 3 2 2 5 9 9 1 1 0 0 2 5 1 1 2 2 1 1 2 2 2 2 14 18 1 0 1 3 1 8 1 7 1 9 1 2 1 13 0 3 7 9 1 2 2 4 2 6 2 5 2 10 4 6 4 11 4 12 8 11 */