hdu4587 Two Nodes 求图中删除两个结点剩余的连通分量的数量
题目链接: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 求图中删除两个结点剩余的连通分量的数量的更多相关文章
- [Swift]LeetCode882. 细分图中的可到达结点 | Reachable Nodes In Subdivided Graph
Starting with an undirected graph (the "original graph") with nodes from 0 to N-1, subdivi ...
- Floyd-Warshall求图中任意两点的最短路径
原创 除了DFS和BFS求图中最短路径的方法,算法Floyd-Warshall也可以求图中任意两点的最短路径. 从图中任取两点A.B,A到B的最短路径无非只有两种情况: 1:A直接到B这条路径即是最短 ...
- 用C语言把双向链表中的两个结点交换位置,考虑各种边界问题。
用C语言把双向链表中的两个结点交换位置,考虑各种边界问题. [参考] http://blog.csdn.net/silangquan/article/details/18051675
- [LeetCode] 882. Reachable Nodes In Subdivided Graph 细分图中的可到达结点
Starting with an undirected graph (the "original graph") with nodes from 0 to N-1, subdivi ...
- [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 ...
- 求二叉树中第K层结点的个数
一,问题描述 构建一棵二叉树(不一定是二叉查找树),求出该二叉树中第K层中的结点个数(根结点为第0层) 二,二叉树的构建 定义一个BinaryTree类来表示二叉树,二叉树BinaryTree 又是由 ...
- hdu 5952 Counting Cliques 求图中指定大小的团的个数 暴搜
题目链接 题意 给定一个\(n个点,m条边\)的无向图,找出其中大小为\(s\)的完全图个数\((n\leq 100,m\leq 1000,s\leq 10)\). 思路 暴搜. 搜索的时候判断要加进 ...
- poj The Settlers of Catan( 求图中的最长路 小数据量 暴力dfs搜索(递归回溯))
The Settlers of Catan Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 1123 Accepted: ...
- 083 Remove Duplicates from Sorted List 有序链表中删除重复的结点
给定一个排序链表,删除所有重复的元素使得每个元素只留下一个.案例:给定 1->1->2,返回 1->2给定 1->1->2->3->3,返回 1->2- ...
随机推荐
- Unique Snowflakes(窗口滑动)
题目: Emily the entrepreneur has a cool business idea: packaging and selling snowflakes. She has devis ...
- [BZOJ 1412][ZJOI 2009] 狼和羊的故事
题目大意 有一个 (n times m) 的网格,每一个格子上是羊.狼.空地中的一种,羊和狼可以走上空地.现要在格子边上建立围栏,求把狼羊分离的最少围栏数. (1 leqslant n, ; m le ...
- install jekyll
最直接的方法就是运行快速指南中的命令: gem install jekyll 这个时候会提示: Command 'gem' not found, but can be installed with: ...
- Python——1变量和数据类型(内含其他知识点链接)
*/ * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:text.cpp * 作者:常轩 * 微信公众号:Worldhe ...
- 浅谈.NET Framework 与CLR
承载公共语言运行时 (CLR) 的所有应用程序均需启动(或称“激活”)CLR 以运行托管代码. 通常,.NET Framework 应用程序在生成它的 CLR ...
- 车道线检测LaneNet
LaneNet LanNet Segmentation branch 完成语义分割,即判断出像素属于车道or背景 Embedding branch 完成像素的向量表示,用于后续聚类,以完成实例分割 H ...
- 生产要不要开启MySQL查询缓存
一.前言 在当今的各种系统中,缓存是对系统性能优化的重要手段.MySQL Query Cache(MySQL查询缓存)在MySQL Server中是默认打开的,但是网上各种资料以及有经验的DBA都建议 ...
- 数据结构-ST表
数据结构-ST表 不可修改,在线查询的 RMQ 问题. 其中 \(f[i][j]\) 表示 \(i\sim i+(1<<j)-1\) 这段的 RMQ 值. 时间复杂度 \(O(n\log ...
- Spring源码阅读笔记04:默认xml标签解析
上文我们主要学习了Spring是如何获取xml配置文件并且将其转换成Document,我们知道xml文件是由各种标签组成,Spring需要将其解析成对应的配置信息.之前提到过Spring中的标签包括默 ...
- SpringBoot图文教程15—项目异常怎么办?「跳转404错误页面」「全局异常捕获」
有天上飞的概念,就要有落地的实现 概念十遍不如代码一遍,朋友,希望你把文中所有的代码案例都敲一遍 先赞后看,养成习惯 SpringBoot 图文教程系列文章目录 SpringBoot图文教程1-Spr ...