题意:求除去任意两点及这两点所连的边的连通分量最大
分析:枚举一点,除去这一点形成了一个新图,然后求割点,因为另外一点肯定是割点,不然无法使连通分量最大!然后计算除去割点的连通分量,最后求最大值即可!
// File Name: test.cpp // Author: Zlbing // Created Time: 2013/5/14 8:23:10 #include<iostream> #include<string> #include<algorithm> #include<cstdlib> #include<cstdio> #include<set> #include<map> #include<vector> #include<cstring> #include<stack> #include<cmath> #include<queue> using namespace std; #define CL(x,v); memset(x,v,sizeof(x)); #define INF 0x3f3f3f3f #define LL long long #define REP(i,r,n) for(int i=r;i<=n;i++) #define RREP(i,n,r) for(int i=n;i>=r;i--) #define MAXN 5000+100 vector<int> G[MAXN]; int pre[MAXN]; int dfs_clock,bcc_cnt; struct Edge{ int u,v; }; vector<Edge> edges; int ans=0; int cnt; int n,m; int f[MAXN]; int find(int x) { return f[x]==x?x:f[x]=find(f[x]); } int dfs(int u,int fa,int a) { int lowu=pre[u]=++dfs_clock; int child=0; // printf("u=%d fa==%d \n",u,fa); int cc=G[u].size(); for(int i=0;i<cc;i++) { int mm=G[u][i]; int v=edges[mm].v; if(v==a)continue; if(!pre[v]) { int lowv=dfs(v,u,a); lowu=min(lowu,lowv); if(lowv>=pre[u]) { // printf("v==%d\n",v); child++; } } else if(pre[v]<pre[u]&&v!=fa) { lowu=min(pre[v],lowu); } } ans=max(ans,cnt-1+child+(fa!=-1)); return lowu; } void find_bcc(int N,int a) { memset(pre,0,sizeof(pre)); dfs_clock=0; bcc_cnt=0; cnt=N-1; int mm=edges.size(); for(int i=0;i<N;i++)f[i]=i; for(int i=0;i<mm;i++) { int u=edges[i].u; int v=edges[i].v; if(u==a||v==a)continue; int fu=find(u); int fv=find(v); //printf("u==%d fu==%d v==%d fv==%d\n",u,fu,v,fv); if(fu!=fv) { cnt--; f[f[u]]=f[v]; } } //printf("a==%d cnt==%d\n",a,cnt); for(int i=0;i<N;i++) if(!pre[i]&&i!=a) dfs(i,-1,a); } int main() { while(~scanf("%d%d",&n,&m)) { edges.clear(); REP(i,0,n){ G[i].clear(); } int a,b; REP(i,1,m) { scanf("%d%d",&a,&b); if(a==b)continue; edges.push_back((Edge){a,b}); edges.push_back((Edge){b,a}); int mm=edges.size(); G[a].push_back(mm-2); G[b].push_back(mm-1); } ans=0; for(int i=0;i<n;i++) { find_bcc(n,i); } printf("%d\n",ans); } return 0; }