hihoCoder 1183 连通性一·割边与割点(Tarjan求割点与割边)
#1183 : 连通性一·割边与割点
描述
还记得上次小Hi和小Ho学校被黑客攻击的事情么,那一次攻击最后造成了学校网络数据的丢失。为了避免再次出现这样的情况,学校决定对校园网络进行重新设计。
学校现在一共拥有N台服务器(编号1..N)以及M条连接,保证了任意两台服务器之间都能够通过连接直接或者间接的数据通讯。
当发生黑客攻击时,学校会立刻切断网络中的一条连接或是立刻关闭一台服务器,使得整个网络被隔离成两个独立的部分。
举个例子,对于以下的网络:
每两个点之间至少有一条路径连通,当切断边(3,4)的时候,可以发现,整个网络被隔离为{1,2,3},{4,5,6}两个部分:
若关闭服务器3,则整个网络被隔离为{1,2},{4,5,6}两个部分:
小Hi和小Ho想要知道,在学校的网络中有哪些连接和哪些点被关闭后,能够使得整个网络被隔离为两个部分。
在上面的例子中,满足条件的有边(3,4),点3和点4。
输入
第1行:2个正整数,N,M。表示点的数量N,边的数量M。1≤N≤20,000, 1≤M≤100,000
第2..M+1行:2个正整数,u,v。表示存在一条边(u,v),连接了u,v两台服务器。1≤u<v≤N
保证输入所有点之间至少有一条连通路径。
输出
第1行:若干整数,用空格隔开,表示满足要求的服务器编号。从小到大排列。若没有满足要求的点,该行输出Null
第2..k行:每行2个整数,(u,v)表示满足要求的边,u<v。所有边根据u的大小排序,u小的排在前,当u相同时,v小的排在前面。若没有满足要求的边,则不输出
- 样例输入
-
6 7
1 2
1 3
2 3
3 4
4 5
4 6
5 6 - 样例输出
-
3 4
3 4
题目链接:hicoCoder 1183
验证一下自己以往的代码是否正确的题目,不过这题十分坑爹,若没有割点,要输出 Null ,WA半天查了题解发现他们都有输出这句……加上去就过了,怪自己眼神不好
第1行:若干整数,用空格隔开,表示满足要求的服务器编号。从小到大排列。若没有满足要求的点,该行输出Null
割点判断:
1、当前点为你一开始tarjan的起始点(即你进入某颗dfs搜索树的第一个点)且它的儿子有两个,前者多传递一个参数就能解决,后者用一个son变量记录这个节点的搜索子树有几颗。
2、当前点不是起始点,但儿子节点的low值大于当前点的dfn[u]值,即儿子边无法返回即$low[v]>=dfn[u]$。
割边判断条件:
比较简单只需要$low[v]>dfn[u]$即可,跟割点一样无法返回,但是由于是针对边的,肯定不能加等于号,代码中加入了重边判断,题目有没有重边不清楚,但是肯定这样写好一点
代码(sublime代码格式化真是好用):
#include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define LC(x) (x<<1)
#define RC(x) ((x<<1)+1)
#define MID(x,y) ((x+y)>>1)
#define CLR(arr,val) memset(arr,val,sizeof(arr))
#define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
typedef pair<int, int> pii;
typedef long long LL;
const double PI = acos(-1.0);
const int N = 20010;
const int M = 100010;
struct edge
{
int to, nxt, id;
};
edge E[M << 1];
int head[N], tot;
int low[N], dfn[N], st[N], top, ts;
bool ins[N], cut[N];
vector<pii>bridge; void init()
{
CLR(head, -1);
tot = 0;
CLR(low, 0);
CLR(dfn, 0);
top = ts = 0;
CLR(ins, false);
bridge.clear();
CLR(cut, false);
}
inline void add(int s, int t, int id)
{
E[tot].to = t;
E[tot].id = id;
E[tot].nxt = head[s];
head[s] = tot++;
}
void Tarjan(int u, int id, const int &rt)
{
low[u] = dfn[u] = ++ts;
st[top++] = u;
ins[u] = 1;
int v, i;
int son = 0;
for (i = head[u]; ~i; i = E[i].nxt)
{
v = E[i].to;
if (E[i].id == id)
continue;
if (!dfn[v])
{
++son;
Tarjan(v, E[i].id, rt);
low[u] = min(low[u], low[v]); if (low[v] > dfn[u])
bridge.push_back(pii(min(u, v), max(u, v))); if (u == rt && son > 1)
cut[u] = 1;
else if (u != rt && low[v] >= dfn[u])
cut[u] = 1;
}
else if (ins[v])
low[u] = min(low[u], dfn[v]);
}
if (low[u] == dfn[u])
{
do
{
v = st[--top];
ins[v] = 0;
} while (u != v);
}
}
int main(void)
{
int n, m, a, b, i;
while (~scanf("%d%d", &n, &m))
{
init();
for (i = 0; i < m; ++i)
{
scanf("%d%d", &a, &b);
add(a, b, i);
add(b, a, i);
}
for (i = 1; i <= n; ++i)
if (!dfn[i])
Tarjan(i, -1, i);
int first = 0;
for (i = 1; i <= n; ++i)
if (cut[i])
printf("%s%d", ++first == 1 ? "" : " ", i);
if (!first)
printf("Null");
putchar('\n');
int sz = bridge.size();
sort(bridge.begin(), bridge.end());
for (i = 0; i < sz; ++i)
printf("%d %d\n", bridge[i].first, bridge[i].second);
}
return 0;
}
hihoCoder 1183 连通性一·割边与割点(Tarjan求割点与割边)的更多相关文章
- tarjan求割点与割边
tarjan求割点与割边 洛谷P3388 [模板]割点(割顶) 割点 解题思路: 求割点和割点数量模版,对于(u,v)如果low[v]>=dfn[u]那么u为割点,特判根结点,若根结点子树有超过 ...
- tarjan求割点割边的思考
这个文章的思路是按照这里来的.这里讨论的都是无向图.应该有向图也差不多. 1.如何求割点 首先来看求割点.割点必须满足去掉其以后,图被分割.tarjan算法考虑了两个: 根节点如果有两颗及以上子树,它 ...
- poj_1144Network(tarjan求割点)
poj_1144Network(tarjan求割点) 标签: tarjan 割点割边模板 题目链接 Network Time Limit: 1000MS Memory Limit: 10000K To ...
- Tarjan求割点和桥
by szTom 前置知识 邻接表存储及遍历图 tarjan求强连通分量 割点 割点的定义 在一个无向图中,如果有一个顶点集合,删除这个顶点集合以及这个集合中所有顶点相关联的边以后,图的连通分量增多, ...
- UESTC 900 方老师炸弹 --Tarjan求割点及删点后连通分量数
Tarjan算法. 1.若u为根,且度大于1,则为割点 2.若u不为根,如果low[v]>=dfn[u],则u为割点(出现重边时可能导致等号,要判重边) 3.若low[v]>dfn[u], ...
- POJ 1144 Network(Tarjan求割点)
Network Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 12707 Accepted: 5835 Descript ...
- poj 1523 SPF(tarjan求割点)
本文出自 http://blog.csdn.net/shuangde800 ------------------------------------------------------------ ...
- 洛谷P3388 【模板】割点(割顶)(tarjan求割点)
题目背景 割点 题目描述 给出一个n个点,m条边的无向图,求图的割点. 输入输出格式 输入格式: 第一行输入n,m 下面m行每行输入x,y表示x到y有一条边 输出格式: 第一行输出割点个数 第二行按照 ...
- [POJ1144][BZOJ2730]tarjan求割点
求割点 一种显然的n^2做法: 枚举每个点,去掉该点连出的边,然后判断整个图是否联通 用tarjan求割点: 分情况讨论 如果是root的话,其为割点当且仅当下方有两棵及以上的子树 其他情况 设当前节 ...
- poj1144 tarjan求割点
poj1144 tarjan求割点 额,算法没什么好说的,只是这道题的读入非常恶心. 注意,当前点x是否是割点,与low[x]无关,只和low[son]和dfn[x]有关. 还有,默代码的时候记住分目 ...
随机推荐
- Linux学习之一--VI编辑器的基本使用
vi编辑器是Linux系统下标准的编辑器.而且不逊色于其他任何最新的编辑器.可是会用的有多少呢.下面介绍一下vi编辑器的简单用法和部分命令.让你在Linux系统中畅行无阻. 基本上vi可以分为三种状态 ...
- 字符串匹配:KMP算法
一.原理: KMP算法是由Knuth,Morris,Pratt共同提出的模式匹配算法,其对于任何模式和目标序列,都可以在线性时间内完成匹配查找,而不会发生退化,是一个非常优秀的模式匹配算法.朴素算法( ...
- SVN 删除误上传到服务器的文件
使用Axure软件的时候,不小心把一些无用的文档也提交到了SVN上了. 当更新服务器上的文件到本地,然后删除误提交的文件时,出现了一个错误,见下图: 错误:cannot verify lock o ...
- Spring基础知识
Spring基础知识 利用spring完成松耦合 接口 public interface IOutputGenerator { public void generateOutput(); } 实现类 ...
- Class.forName的使用
Class.forName的使用 Class.forName返回一个类,使用此方法可以获取类 首先,创建一个Student类 /*** * This Class is for Student bean ...
- Pyqt 获取动态生成的QLineEdit值
动态生成控件参考上一篇: http://www.cnblogs.com/dcb3688/p/4588814.html 那如何获取动态生成控件的值呢? 比如,动态的生成10个输入框QLineEdit,输 ...
- angular 依赖注入原理
依赖注入(Dependency Injection,简称DI)是像C#,java等典型的面向对象语言框架设计原则控制反转的一种典型的一种实现方式,angular把它引入到js中,介绍angular依赖 ...
- Unix系统引导过程(简单步骤)
1.从MBR中读取引导加载程序(boot loader) 2.初始化内核 3.硬件检测 4.创建内核进程 5.系统管理员干预(仅仅在进入单用户模式或者恢复模式的时候) 6.执行系统启动脚本
- kkjcre1p: unable to spawn jobq slave process, slot 0, error 1089(Linux x86_64)补丁
在shutdown immediately的时候,alert Log出现如下错误信息,并且不能正常关闭 kkjcre1p: unable to spawn jobq slave process, sl ...
- 【leetcode】Search Insert Position
题目描述: Given a sorted array and a target value, return the index if the target is found. If not, retu ...