HDU 4587 TWO NODES(割两个点的最大连通分支数)

http://acm.hdu.edu.cn/showproblem.php?pid=4587

题意:

给一图,求割去两个点后所能形成的最大连通分支数。

思路:

对于这种情况,第一个只能枚举,然后在删除第一个点的前提下,用Tarjan算法求第二个割点的情况。

 #include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<sstream>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
typedef pair<int,ll> pll;
const int INF = 0x3f3f3f3f;
const int maxn=+; int n, m;
int tot;
int dfs_clock;
int pre[maxn];
int cut[maxn];
int low[maxn];
int head[*maxn];
int del; struct node
{
int v,next;
}e[*maxn]; void addEdge(int u, int v)
{
e[tot].v=v;
e[tot].next=head[u];
head[u]=tot++;
} int tarjan(int u, int fa)
{
int lowu=pre[u]=++dfs_clock;
for(int i=head[u];i!=-;i=e[i].next)
{
int v=e[i].v;
if(v==del) continue;
if(!pre[v])
{
int lowv = tarjan(v,u);
lowu=min(lowu,lowv);
if(lowv>=pre[u]) cut[u]++;
}
else if(v!=fa)
lowu=min(lowu,pre[v]);
}
if(fa<) cut[u]--;
return low[u]=lowu;
} int solve()
{
int cnt=;
dfs_clock=;
memset(cut,,sizeof(cut));
memset(pre,,sizeof(pre));
for(int i=;i<n;i++)
{
if(del!=i && !pre[i])
{
cnt++;
tarjan(i,-);
}
}
int ans=;
for(int i=;i<n;i++)
{
if(i!=del) ans=max(ans,cnt+cut[i]);
}
return ans;
} int main()
{
//freopen("in.txt","r",stdin);
while(~scanf("%d%d",&n,&m))
{
tot=;
memset(head,-,sizeof(head));
for(int i=;i<m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
addEdge(u,v);
addEdge(v,u);
}
int ans=-;
for(int i=;i<n;i++)
{
del=i;
ans=max(ans,solve());
}
printf("%d\n",ans);
}
return ;
}
上一篇:【uoj291】 ZJOI2017—树状数组


下一篇:When Startup Disk is Full