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- ...
随机推荐
- Google Play来华 象征意义 跳板而已
Play来华 象征意义 跳板而已" title="Google Play来华 象征意义 跳板而已"> 每当有大事发生,伴随的就是接连不断的小道消息传出来.就像苹 ...
- iOS多线程开发之GCD(基础篇)
总纲: GCD基本概念 GCD如何实现 GCD如何使用 队列和任务组合 一.GCD基本概念 GCD 全称Grand Central Dispatch(大中枢队列调度),是一套低层API,提供了⼀种新的 ...
- 远程桌面协议RDP
远程桌面协议RDP(Remove Desktop Protocol) 通过mstsc客户端远程连接计算机,并对其进行管理等操作. 与TELNET的区别在于,TELNET显示的是远程计算机的命令行窗口, ...
- 达拉草201771010105《面向对象程序设计(java)》第六周学习总结
达拉草201771010105<面向对象程序设计(java)>第六周学习总结 第一部分:理论知识 1.类.超类和子类 类继承的格式: class 新类名extends已有类名一般来说,子类 ...
- flask-restful 初探
flask-restful 是 Flask 的一个用于支持 RESTful 的插件. 刚开始用对我来说还是比较坑的... 目录结构 / /test /test/common /__init__.py ...
- SpringBoot图文教程10—模板导出|百万数据Excel导出|图片导出「easypoi」
有天上飞的概念,就要有落地的实现 概念十遍不如代码一遍,朋友,希望你把文中所有的代码案例都敲一遍 先赞后看,养成习惯 SpringBoot 图文教程系列文章目录 SpringBoot图文教程1「概念+ ...
- Spring 事务传播机制和数据库的事务隔离级别
Propagation(事务传播属性) 类别 传播类型 说明 支持当前事务 REQUIRED 如果当前没有事务,就新建一个事务.@Transaction的默认选择 支持当前事务 SUPPORTS 就以 ...
- js 打开新窗口方式
之前的项目,有个功能是下载文件,这里只要在浏览器输入 url 就会下载那个文件了.当时我只是简单得使用 window.open ,但是却会被浏览器进行拦截,要手动开启才行,然后就搜索研究其他方法,就看 ...
- 在Shadow DOM使用原生模板
原生模板的优势 延迟了资源加载 延迟了加载和处理模板所引用的资源的时机,这样,用户就能够在模板中使用任意多的资源,却不阻碍页面的渲染. 延迟了渲染内容 无论模板在什么位置,浏览器不会把模板中的内容直接 ...
- 判断某个点是否在某个view上
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *touch = [touches anyObjec ...