题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4587

题目给了12000ms,对于tarjan这种O(|V|+|E|)复杂度的算法来说,暴力是能狗住的。可以对每个点进行枚举,然后对剩余的网络进行tarjan,对割点所能造成的最大的连通分量进行查询,也就是如下的方程。ans=max{cut[i]}+cnt 其中cnt删除第一个结点之后剩下的网络在初始时刻的连通分量的数量,也就是对每一个第一结点tarjan进行深搜的次数。另外,这次的tarjan中的cut数组存储的不再是这个点是否是割点,而是这个点“成为割点的次数”,也就是说,对于一个非根节点u来说,他有k个分支只能通过u来连接到u的祖先,所以u被删除之后就会多出来k个连通分量,这个cut的更新是在搜索完一个分支之后退回到u时更新的。对于根节点来说,由于他没有父结点,原先他所在的连通分量的分量数量为1,现在把它割掉,还剩k个子树的连通分量,也就是根节点使得连通分量的数量增加了k-1,这是不同于非根节点的。

注意根节点能增加的连通分量的数量的更新方式!对于根节点删除能增加多少子连通图数量,只要判断是不是父节点就可以,不应判断子树的数量,因为如果子树的数量大于1的话增加的连通块数量是child-1,当这个点是孤立点的时候删除这个结点的话连通块的数量实际上是减少的!!!!

代码如下:

 #include<bits/stdc++.h>
using namespace std;
typedef unsigned int ui;
typedef long long ll;
typedef unsigned long long ull;
#define pf printf
#define mem(a,b) memset(a,b,sizeof(a))
#define prime1 1e9+7
#define prime2 1e9+9
#define pi 3.14159265
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define scand(x) scanf("%llf",&x)
#define f(i,a,b) for(int i=a;i<=b;i++)
#define scan(a) scanf("%d",&a)
#define mp(a,b) make_pair((a),(b))
#define P pair<int,int>
#define dbg(args) cout<<#args<<":"<<args<<endl;
#define inf 0x3f3f3f3f
const int maxn=;
const int maxm=;
int n,m,t;
int head[maxn],nxt[maxm],cut[maxn],dfn[maxn],low[maxn];
struct node{
int u,v;
}p[maxm];
int e;
int first;
int id;
void addedge(int u,int v)
{
p[e].u=u;
p[e].v=v;
nxt[e]=head[u];
head[u]=e++;
}
void tarjan(int u,int fa)
{
dfn[u]=low[u]=++id;
int child=;
for(int i=head[u];~i;i=nxt[i])
{
int v=p[i].v;
if(v==first||v==fa)continue;//假定了这个网络中没有first结点
if(!dfn[v])
{
child++;
tarjan(v,u);
low[u]=min(low[u],low[v]);
if(low[v]>=dfn[u]&&u!=fa)cut[u]++;//非根结点成为割点,可割的连通分量的数量增加
}
else if(dfn[v]<dfn[u]&&v!=fa)
{
low[u]=min(low[u],dfn[v]);
}
}
//下面这句更新方法是错误的,因为当儿子结点的个数是0的时候这个点就是孤立点,如果把它删去连通分量的数量会减少1!!!!!
// if(u==fa&&child>=1)cut[u]=child-1;
if(u==fa&&child>=)cut[u]=child-; //更新根节点的cut值的唯一方法是通过子树的数量-1
//注意此时如果根节点的child值是1的话更新之后是0,所以不能加child>1的条件
}
int main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
std::ios::sync_with_stdio(false);
while(scanf("%d%d",&n,&m)!=EOF)
{
int x,y;
f(i,,maxn-)head[i]=-,nxt[i]=-;
e=;
f(i,,m)
{
scanf("%d%d",&x,&y);
addedge(x,y);
addedge(y,x);
}
int curnum;
int ans=;
f(i,,n-)//枚举每一个点,再用tarjan对割点进行查找,找到割点增加连通分量最多的点。
{
f(j,,n-)dfn[j]=,cut[j]=;//要进行n次对这个网络的tarjan,每次都要清零
first=i;
curnum=;
id=;
f(j,,n-)
{
if(i==j)continue;
if(!dfn[j])
{
tarjan(j,j);
curnum++;
}
}
f(j,,n-)
{
if(j!=i) ans=max(ans,curnum+cut[j]);
}
}
pf("%d\n",ans);
}
return ;
}

hdu4587 Two Nodes 求图中删除两个结点剩余的连通分量的数量的更多相关文章

  1. [Swift]LeetCode882. 细分图中的可到达结点 | Reachable Nodes In Subdivided Graph

    Starting with an undirected graph (the "original graph") with nodes from 0 to N-1, subdivi ...

  2. Floyd-Warshall求图中任意两点的最短路径

    原创 除了DFS和BFS求图中最短路径的方法,算法Floyd-Warshall也可以求图中任意两点的最短路径. 从图中任取两点A.B,A到B的最短路径无非只有两种情况: 1:A直接到B这条路径即是最短 ...

  3. 用C语言把双向链表中的两个结点交换位置,考虑各种边界问题。

    用C语言把双向链表中的两个结点交换位置,考虑各种边界问题. [参考] http://blog.csdn.net/silangquan/article/details/18051675

  4. [LeetCode] 882. Reachable Nodes In Subdivided Graph 细分图中的可到达结点

    Starting with an undirected graph (the "original graph") with nodes from 0 to N-1, subdivi ...

  5. [LintCode] Swap Two Nodes in Linked List 交换链表中的两个结点

    Given a linked list and two values v1 and v2. Swap the two nodes in the linked list with values v1 a ...

  6. 求二叉树中第K层结点的个数

    一,问题描述 构建一棵二叉树(不一定是二叉查找树),求出该二叉树中第K层中的结点个数(根结点为第0层) 二,二叉树的构建 定义一个BinaryTree类来表示二叉树,二叉树BinaryTree 又是由 ...

  7. hdu 5952 Counting Cliques 求图中指定大小的团的个数 暴搜

    题目链接 题意 给定一个\(n个点,m条边\)的无向图,找出其中大小为\(s\)的完全图个数\((n\leq 100,m\leq 1000,s\leq 10)\). 思路 暴搜. 搜索的时候判断要加进 ...

  8. poj The Settlers of Catan( 求图中的最长路 小数据量 暴力dfs搜索(递归回溯))

    The Settlers of Catan Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1123   Accepted: ...

  9. 083 Remove Duplicates from Sorted List 有序链表中删除重复的结点

    给定一个排序链表,删除所有重复的元素使得每个元素只留下一个.案例:给定 1->1->2,返回 1->2给定 1->1->2->3->3,返回 1->2- ...

随机推荐

  1. Logback 标准xml参考

    强制: [强制]应用中不可直接使用日志系统(Log4j.Logback)中的 API,而应依赖使用日志框架SLF4J 中的 API,使用门面模式的日志框架,有利于维护和各个类的日志处理方式统一.imp ...

  2. MySQL安装和常用命令

    一.安装MySQL groupadd mysqluseradd -r -g mysql mysqlgroups mysqlfind / -name mysql | xargs rm -rfwget h ...

  3. uboot--tftp

    一.      概述 U-boot中的TFTP用于发送较小的文件.下层使用UDP协议,发送使用UDP 69端口,每次发送的最大分组为512 Bytes.发送双方采用超时重传机制.数据传输模式为octe ...

  4. C++扬帆远航——5(换分币)

    /* * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:huanfenbi.cpp * 作者:常轩 * 完成日期:201 ...

  5. C++走向远洋——68(十六周、文件)

    */ * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:text.cpp * 作者:常轩 * 微信公众号:Worldhe ...

  6. 微信小程序采坑之scroll-view

    当设置了scroll-y为true之后,纵向是没有问题的,会出现滚动条. Android上一切都是那么的祥和, ios上你会发现如果你scroll-view里面的东西超过横向的宽度时,就会隐藏了. 也 ...

  7. SpringBoot入门系列(一)如何快速创建SpringBoot项目

    这段时间也没什么事情,所以就重新学习整理了Spring Boot的相关内容.今天开始整理更新Spring Boot学习笔记,感兴趣的朋友可以关注我的博客:https://www.cnblogs.com ...

  8. 自定义 ---UICollectionViewLayout-正N变形居中布局

    1. 自定义UICollectionLayout ---- 正三角形居中布局 支持多个图形的自动布局 2. 自定义UICollectionLayout ---- 正方形居中布局 滚动展示的区域 3.  ...

  9. redis01

    1.redis 1)cookie与session session本质上也是cookie,cookie携带session返回给服务端 redis是一个存储数据库 redis读写快速,使用简单,常用于存储 ...

  10. All In One

    set1 https://github.com/tianhang-f... set2 https://github.com/tianhang/F... set3https://github.com/t ...