tarjin求割点
题目: hdu3671
http://acm.hdu.edu.cn/showproblem.php?pid=3671
题意:给一个无向图,要求毁掉两个点,使图变得不连通,图一开始是连通的
因为要毁掉两个点,就不是简单的求割点,再看看数据范围,点数为1000,边数为10000,Tarjan的时间复杂度为O(E),如果用枚举法,先枚举要毁掉的第一个点,再用Tarjan进行处理来找割点会不会超时呢?答案是不会,时间为O(v*E),刚好是千万级别,不超
做法:先枚举要删除的第1个点,在原图中删除它,看看删除它后整个图的变化
1.整个图变得不连通了(即这个点本身是割点),但是还没完要分类讨论一下
(1).整个图变为两部分,但是两部分刚好都是一个点,那么这两个点再毁掉哪个点都好,图的连通分支数都不
会增加,这是一个特殊情况
例如,(1,2)(2,3)这种图,是无解的,任意毁掉两个点都无法增加图的连通分支,所以方案数为0
(2).整个图分为两部分,但是有一部分的点数为1,另一部分大于1,那么这时候只要在较大的那部分,任意毁掉一个点(无论是不是割点都行),最后整个图都会至少被分为了两个部分
(如果毁掉的是割点,将分成更多份),所以这样产生的方案数是V-2
(3).整个图分为了两个部分,两个部分的点数都大于1,那么任意在哪个部分毁掉那个点都可以(无论是不是割点都行),最后整个图都会至少分为两个部分,所以方案数为V-1
(4).整个图被分为了三个或更多的部分,那么也是在剩下的点中任意毁掉一个点都可以(无论那个点是不是割点),方案数为V-1
(如果这个点刚好处于一个部分且这个部分只有它自己一个点,那么 毁掉后整个图的分支数减1;如果这个点在一个部分且这个部分不止它一个点且这个点不是割点,那么分支数 不会增加,如果是割点分支数为增加)
2.删除第一个点后,整个图还是连通的(是连通,不是双连通)
那么就在剩下的图中找割点,找到几个,方案数就是多少
最后注意一点,这样计算的结果,很容易想到是有重复的,但是不难想到,其实刚好重复了一次,因为对于一个图,方案是固定的,枚举了所有点,找出了所有已方案,相当于每个方案算了两次,最后答案除2即可
#include<iostream>
#include<cstring>
//#include<bits/stdc++.h>
#include<math.h>
#include<algorithm>
#include<queue>
#include<stack>
#include<cstdio>
#include<map>
#include<set>
#define si(a) scanf("%d",&a)
#define sl(a) scanf("%lld",&a)
#define sii(a,b) scanf("%d%d",&a,&b)
#define sll(a,b) scanf("%lld%lld",&a,&b)
#define queues priority_queue
#define mod 1000000007
#define mem(a) memset(a,0,sizeof(a));
#define def(a) ((a)&(-a))
#define mp make_pair
#define pb push_back
#define fi first
#define se second
typedef long long ll;
const int INF=0x3f3f3f3f;
using namespace std;
const int MAX=;
vector<int>q[MAX];
int DFN[MAX];
int VIM[MAX];
int top;
int clore;
int num;
set<int>s;
void tarjan(int a,int fa,int d)
{
int child=;
DFN[a]=VIM[a]=++top;
num++;
for(int i:q[a])
{
if(i==fa||i==d)continue;
if(!DFN[i])
{
child++;
tarjan(i,a,d);
VIM[a]=min(VIM[a],VIM[i]);
if(VIM[i]>=DFN[a]&&a!=fa)
s.insert(a);
}
else VIM[a]=min(VIM[a],DFN[i]);
}
if(a==fa&&child>=)s.insert(a);
}
int main()
{
int n,m;
int z=;
while(cin>>n>>m&&n+m)
{
int sum=;
top=;
for(int i=; i<=n; i++)
q[i].clear();
for(int i=; i<=m; i++)
{
int a,b;
cin>>a>>b;
q[a].push_back(b);
q[b].push_back(a);
}
for(int i=; i<=n; i++)
{
int count1=;
int ok=;
clore=;
s.clear();
mem(VIM);
mem(DFN);
for(int j=; j<=n; j++)
if(j!=i&&!DFN[j])
{
count1++;
num=;
tarjan(j,j,i);
if(num==)ok++;
}
if(count1>=)sum+=n-;
else if(count1==&&ok==)sum+=n-;
else if(count1==&&ok==)sum+=n-;
else if(count1==)sum+=s.size();
}
printf("Case %d: %d\n",++z,sum/);
} }
tarjin求割点的更多相关文章
- Tarjan应用:求割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)【转】【修改】
一.基本概念: 1.割点:若删掉某点后,原连通图分裂为多个子图,则称该点为割点. 2.割点集合:在一个无向连通图中,如果有一个顶点集合,删除这个顶点集合,以及这个集合中所有顶点相关联的边以后,原图变成 ...
- poj1523 求割点 tarjan
SPF Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 7678 Accepted: 3489 Description C ...
- [学习笔记]tarjan求割点
都口胡了求割边,就顺便口胡求割点好了QAQ 的定义同求有向图强连通分量. 枚举当前点的所有邻接点: 1.如果某个邻接点未被访问过,则访问,并在回溯后更新 2.如果某个邻接点已被访问过,则更新 对于当前 ...
- tarjan算法求割点cojs 8
tarjan求割点:cojs 8. 备用交换机 ★★ 输入文件:gd.in 输出文件:gd.out 简单对比时间限制:1 s 内存限制:128 MB [问题描述] n个城市之间有通讯网 ...
- UESTC 900 方老师炸弹 --Tarjan求割点及删点后连通分量数
Tarjan算法. 1.若u为根,且度大于1,则为割点 2.若u不为根,如果low[v]>=dfn[u],则u为割点(出现重边时可能导致等号,要判重边) 3.若low[v]>dfn[u], ...
- loj 1063(求割点个数)
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=26780 思路:判断一个点是否是割点的两个条件:1.如果一个点v是根 ...
- POJ 1144 Network(Tarjan求割点)
Network Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 12707 Accepted: 5835 Descript ...
- (转)Tarjan应用:求割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)
基本概念: 1.割点:若删掉某点后,原连通图分裂为多个子图,则称该点为割点. 2.割点集合:在一个无向连通图中,如果有一个顶点集合,删除这个顶点集合,以及这个集合中所有顶点相关联的边以后,原图变成多个 ...
- 2013 ACM/ICPC南京邀请赛B题(求割点扩展)
题目链接:http://icpc.njust.edu.cn/Contest/194/Problem/B B - TWO NODES 时间限制: 10000 MS 内存限制: 65535 KB 问题描述 ...
随机推荐
- python静态属性的理解
python中并没有像 C语言 C++ java 那样定义静态属性的关键字 static 那么在python中是怎么做的呢? class A(object): name="lance&quo ...
- Windows10搭建FTP服务
1.启用Windows10 Ftp服务 打开控制面板->程序和功能->启用或关闭windows功能然后如图: 2.配置FTP用户 我的电脑->右击点击管理->本地用户和组 在A ...
- Apache Hadoop 2.9.2 的快照管理
Apache Hadoop 2.9.2 的快照管理 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 快照相当于对目录做一个备份.并不会立即复制所有文件,而是指向同一个文件.当写入发生 ...
- JAVA中循环删除list中元素的方法总结【转】
印象中循环删除list中的元素使用for循环的方式是有问题的,但是可以使用增强的for循环,然后今天在使用时发现报错了,然后去科普了一下,再然后发现这是一个误区.下面就来讲一讲..伸手党可直接跳至文末 ...
- C++与蓝图互调
Kismet库 蓝图方法cpp使用 例:打LOG:Print String 蓝图节点的鼠标tips:Target is Kismet System Library #include "Run ...
- L2-007 家庭房产 (25 分) (并查集)
链接:https://pintia.cn/problem-sets/994805046380707840/problems/994805068539215872 题目: 给定每个人的家庭成员和其自己名 ...
- 找到多个与名为“Home”的控制器匹配的类型。解决方法
“/”应用程序中的服务器错误. 找到多个与名为“Home”的控制器匹配的类型.如果为此请求(“{controller}/{action}/{id}”)提供服务的路由没有指定命名空间以搜索与此请求相匹配 ...
- Appnium-API-Dvice
Device Activity Start Activity Start an Android activity by providing package name and activity name ...
- 【转】子类会调用父类的@PostConstruct方法
如果一个类用@Service或@Component,那么只需要用@PostConstruct修饰某个方法,该方法能在类实例化的过程中自动执行,相当于类的构造函数.同时,具备了构造函数不具备的功能. @ ...
- 利用android studio 生成 JNI需要的动态库so文件
JNI: Java Native Interface, 提供了java语言和其他语言(例如c和c++)进行相互调用的方式. 本文是用java调用c生成的so模式.其中,编译so文件过程如下: 1) ...