标签:
http://acm.hdu.edu.cn/showproblem.php?pid=4587
4 5 0 1 1 2 2 3 3 0 0 2
2
/** hdu4587 求割点变形 题目大意:给定一个图,去掉其中哪两点后能得到最多的连通块,是多少 解题思路:枚举去掉第一个点,然后利用求割点的模板就可以求出去掉另一点后的答案,取最多即可 */ #include <stdio.h> #include <string.h> #include <algorithm> #include <iostream> using namespace std; const int maxn=5010; struct note { int v,next; bool cut; } edge[maxn*2]; int head[maxn],ip; void init() { memset(head,-1,sizeof(head)); ip=0; } int low[maxn],dfn[maxn],st[maxn],dex,top; bool inst[maxn],cut[maxn]; int add_block[maxn]; int bridge; int n,m,now; void addedge(int u,int v) { edge[ip].v=v,edge[ip].next=head[u],head[u]=ip++; } void tarjan(int u,int pre) { low[u]=dfn[u]=++dex; st[top++]=u; inst[u]=true; int son=0; for(int i=head[u]; i!=-1; i=edge[i].next) { int v=edge[i].v; if(v==pre)continue; if(v==now)continue; if(!dfn[v]) { son++; tarjan(v,u); if(low[u]>low[v])low[u]=low[v]; if(low[v]>dfn[u]) { bridge++; edge[i].cut=true; edge[i^1].cut=true; } if(u!=pre&&low[v]>=dfn[u]) { cut[u]=true; add_block[u]++; } } else if(low[u]>dfn[v]) { low[u]=dfn[v]; } } if(u==pre&&son>1)cut[u]=true; if(u==pre)add_block[u]=son-1; inst[u]=false; top--; } int solve() { memset(dfn,0,sizeof(dfn)); memset(inst,false,sizeof(inst)); memset(add_block,0,sizeof(add_block)); memset(cut,false,sizeof(cut)); dex=top=0; bridge=0; int cnt=0; for(int i=0;i<n;i++) { if(i!=now&&!dfn[i]) { cnt++; tarjan(i,i); } } int ans=-1; for(int i=0;i<n;i++) { if(i!=now) { ans=max(ans,cnt+add_block[i]); } } return ans; } int main() { while(~scanf("%d%d",&n,&m)) { init(); for(int i=0;i<m;i++) { int u,v; scanf("%d%d",&u,&v); addedge(u,v); addedge(v,u); } int ans=-1; for(int i=0;i<n;i++) { now=i; ans=max(ans,solve()); } printf("%d\n",ans); } return 0; }
标签:
原文地址:http://blog.csdn.net/lvshubao1314/article/details/44025035