Electricity POJ - 2117 + SPF POJ - 1523 去除割点后求强连通分量个数问题
Electricity POJ - 2117
题目描述
Blackouts and Dark Nights (also known as ACM++) is a company that provides electricity. The company owns several power plants, each of them supplying a small area that surrounds it. This organization brings a lot of problems - it often happens that there is not enough power in one area, while there is a large surplus in the rest of the country.
ACM++ has therefore decided to connect the networks of some of the plants together. At least in the first stage, there is no need to connect all plants to a single network, but on the other hand it may pay up to create redundant connections on critical places - i.e. the network may contain cycles. Various plans for the connections were proposed, and the complicated phase of evaluation of them has begun.
One of the criteria that has to be taken into account is the reliability of the created network. To evaluate it, we assume that the worst event that can happen is a malfunction in one of the joining points at the power plants, which might cause the network to split into several parts. While each of these parts could still work, each of them would have to cope with the problems, so it is essential to minimize the number of parts into which the network will split due to removal of one of the joining points.
Your task is to write a software that would help evaluating this risk. Your program is given a description of the network, and it should determine the maximum number of non-connected parts from that the network may consist after removal of one of the joining points (not counting the removed joining point itself).
输入格式
The input consists of several instances.
The first line of each instance contains two integers 1 <= P <= 10 000 and C >= 0 separated by a single space. P is the number of power plants. The power plants have assigned integers between 0 and P - 1. C is the number of connections. The following C lines of the instance describe the connections. Each of the lines contains two integers 0 <= p1, p2 < P separated by a single space, meaning that plants with numbers p1 and p2 are connected. Each connection is described exactly once and there is at most one connection between every two plants.
The instances follow each other immediately, without any separator. The input is terminated by a line containing two zeros.
输出格式
The output consists of several lines. The i-th line of the output corresponds to the i-th input instance. Each line of the output consists of a single integer C. C is the maximum number of the connected parts of the network that can be obtained by removing one of the joining points at power plants in the instance.
样例
Sample Input
3 3
0 1
0 2
2 1
4 2
0 1
2 3
3 1
1 0
0 0
Sample Output
1
2
2
题目大意
求删除一个点后所得连通分量数的最大值
分析
实际上我们只需要在割点中选取删除的点就可以了
为什么呢,因为割点的定义是这样的:在一个无向图中,如果有一个顶点集合,删除这个顶点集合以及这个集合中所有顶点相关联的边以后,图的连通分量增多,就称这个点集为割点集合。
所以,我们先Tarjan一下,求出所有的割点
那么对于每一个割点,如果我们都进行一次dfs的话,显然会T掉
所以我们考虑一下其他的方法
实际上,我们可以在进行Tarjan的过程中稍微做一下改动
我们把cut[i]重新定义为将割点i删除后增加的联通分量个数
每次遇到low[u]>=dfn[now]我们就把cut[now]++
这样我们在统计结果时只需要枚举cut[i]的最大值就可以了
再把这个最大值加上原图中联通块的个数
要特别注意的是,对于根节点,要在最后把cut值减去一(想想这是为什么)
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn=400005;
int head[maxn],dfn[maxn],low[maxn],cut[maxn];
int tot=2,cnt=0;
struct asd{
int from,to,next;
}b[maxn];
void ad(int aa,int bb){
b[tot].from=aa;
b[tot].to=bb;
b[tot].next=head[aa];
head[aa]=tot++;
}
int dfnc;
void tarjan(int now,int fa){
low[now]=dfn[now]=++dfnc;
for(int i=head[now];i!=-1;i=b[i].next){
int u=b[i].to;
if(!dfn[u]){
tarjan(u,now);
low[now]=min(low[now],low[u]);
if(fa==-1) cut[now]++;
if(fa!=-1 && low[u]>=dfn[now]){
cut[now]++;
}
}
else if(u!=fa){
low[now]=min(low[now],dfn[u]);
}
}
}
int main(){
int m,n;
while(scanf("%d%d",&n,&m)!=EOF && n!=0){
memset(&b,0,sizeof(struct asd));
memset(head,-1,sizeof(head));
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(cut,0,sizeof(cut));
dfnc=0,tot=1,cnt=0;
for(int i=1;i<=m;i++){
int aa,bb;
scanf("%d%d",&aa,&bb);
ad(aa,bb),ad(bb,aa);
}
for(int i=0;i<n;i++){
if(!dfn[i]){
tarjan(i,-1);
cut[i]--;
cnt++;
}
}
int ans=-0x3f3f3f3f;
for(int i=0;i<n;i++){
ans=max(ans,cut[i]);
}
printf("%d\n",ans+cnt);
}
return 0;
}
SPF POJ - 1523
题目描述
Consider the two networks shown below. Assuming that data moves around these networks only between directly connected nodes on a peer-to-peer basis, a failure of a single node, 3, in the network on the left would prevent some of the still available nodes from communicating with each other. Nodes 1 and 2 could still communicate with each other as could nodes 4 and 5, but communication between any other pairs of nodes would no longer be possible.
Node 3 is therefore a Single Point of Failure (SPF) for this network. Strictly, an SPF will be defined as any node that, if unavailable, would prevent at least one pair of available nodes from being able to communicate on what was previously a fully connected network. Note that the network on the right has no such node; there is no SPF in the network. At least two machines must fail before there are any pairs of available nodes which cannot communicate.
Input
The input will contain the description of several networks. A network description will consist of pairs of integers, one pair per line, that identify connected nodes. Ordering of the pairs is irrelevant; 1 2 and 2 1 specify the same connection. All node numbers will range from 1 to 1000. A line containing a single zero ends the list of connected nodes. An empty network description flags the end of the input. Blank lines in the input file should be ignored.
Output
For each network in the input, you will output its number in the file, followed by a list of any SPF nodes that exist.
The first network in the file should be identified as "Network #1", the second as "Network #2", etc. For each SPF node, output a line, formatted as shown in the examples below, that identifies the node and the number of fully connected subnets that remain when that node fails. If the network has no SPF nodes, simply output the text "No SPF nodes" instead of a list of SPF nodes.
样例
Sample Input
1 2
5 4
3 1
3 2
3 4
3 5
0
//空格
1 2
2 3
3 4
4 5
5 1
0
//空格
1 2
2 3
3 4
4 6
6 3
2 5
5 1
0
//空格
0
Sample Output
Network #1
SPF node 3 leaves 2 subnets
//空格
Network #2
No SPF nodes
//空格
Network #3
SPF node 2 leaves 2 subnets
SPF node 3 leaves 2 subnets
分析
一样的套路,注意输出的时候要输出两个换行符
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn=100005;
int head[maxn],dfn[maxn],low[maxn],cut[maxn];
int tot=2,cnt=0;
struct asd{
int from,to,next;
}b[maxn];
void ad(int aa,int bb){
b[tot].from=aa;
b[tot].to=bb;
b[tot].next=head[aa];
head[aa]=tot++;
}
int dfnc;
void tarjan(int now,int fa){
low[now]=dfn[now]=++dfnc;
for(int i=head[now];i!=-1;i=b[i].next){
int u=b[i].to;
if(!dfn[u]){
tarjan(u,now);
low[now]=min(low[now],low[u]);
if(fa==-1) cut[now]++;
if(fa!=-1 && low[u]>=dfn[now]){
cut[now]++;
}
}
else if(u!=fa){
low[now]=min(low[now],dfn[u]);
}
}
}
bool jl[maxn];
int js;
int main(){
int m,n;
while(scanf("%d",&m)!=EOF && m!=0){
js++;
memset(&b,0,sizeof(struct asd));
memset(head,-1,sizeof(head));
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(cut,0,sizeof(cut));
memset(jl,0,sizeof(jl));
dfnc=0,tot=1,cnt=0;
scanf("%d",&n);
ad(n,m),ad(m,n);
jl[m]=1,jl[n]=1;
int aa,bb;
while(scanf("%d",&aa)!=EOF && aa!=0){
scanf("%d",&bb);
ad(aa,bb),ad(bb,aa);
jl[aa]=1,jl[bb]=1;
}
for(int i=1;i<maxn;i++){
if(!dfn[i] && jl[i]){
tarjan(i,-1);
cnt++;
cut[i]--;
}
}
printf("Network #%d\n",js);
int ans=0;
for(int i=1;i<maxn;i++){
if(cut[i] && jl[i]) ans++;
}
if(ans==0){
printf(" No SPF nodes\n\n");
continue;
} else {
for(int i=1;i<maxn;i++){
if(cut[i] && jl[i]){
printf(" SPF node %d leaves %d subnets\n",i,cut[i]+cnt);
}
}
}
printf("\n");
}
return 0;
}
Electricity POJ - 2117 + SPF POJ - 1523 去除割点后求强连通分量个数问题的更多相关文章
- tarjan求强连通分量+缩点+割点以及一些证明
“tarjan陪伴强联通分量 生成树完成后思路才闪光 欧拉跑过的七桥古塘 让你 心驰神往”----<膜你抄> 自从听完这首歌,我就对tarjan开始心驰神往了,不过由于之前水平不足,一 ...
- Tarjan求强连通分量,缩点,割点
Tarjan算法是由美国著名计算机专家发明的,其主要特点就是可以求强连通分量和缩点·割点. 而强联通分量便是在一个图中如果有一个子图,且这个子图中所有的点都可以相互到达,这个子图便是一个强连通分量,并 ...
- tarjan求强连通分量+缩点+割点/割桥(点双/边双)以及一些证明
“tarjan陪伴强联通分量 生成树完成后思路才闪光 欧拉跑过的七桥古塘 让你 心驰神往”----<膜你抄> 自从听完这首歌,我就对tarjan开始心驰神往了,不过由于之前水平不足,一 ...
- Tarjan算法打包总结(求强连通分量、割点和Tarjan-LCA)
目录 Tarjan打包总结(求强连通分量.割点和Tarjan-LCA) 强连通分量&缩点 原理 伪代码 板子(C++) 割点 原理 伪代码 最近公共祖先(LCA) 原理 伪代码 板子 Tarj ...
- Tarjan求强连通分量、求桥和割点模板
Tarjan 求强连通分量模板.参考博客 #include<stdio.h> #include<stack> #include<algorithm> using n ...
- POJ 1236 Network of Schools(tarjan求强连通分量+思维)
题目链接:http://poj.org/problem?id=1236 题目大意: 给你一个网络(有向图),有两个任务: ①求出至少同时需要几份副本可以使得整个网络都获得副本 ②至少添加多少信息表(有 ...
- tarjan算法+缩点:求强连通分量 POJ 2186
强连通分量:1309. [HAOI2006]受欢迎的牛 ★★ 输入文件:cow.in 输出文件:cow.out 简单对比时间限制:1 s 内存限制:128 MB [题目描述] 每一头牛 ...
- poj 2186 tarjan求强连通分量
蕾姐讲过的例题..玩了两天后才想起来做 貌似省赛之后确实变得好懒了...再努力两天就可以去北京玩了! 顺便借这个题记录一下求强连通分量的算法 1 只需要一次dfs 依靠stack来实现的tarjan算 ...
- Poj 1904 King's Quest 强连通分量
题目链接: http://poj.org/problem?id=1904 题意: 有n个王子和n个公主,王子只能娶自己心仪的公主(一个王子可能会有多个心仪的公主),现已给出一个完美匹配,问每个王子都可 ...
随机推荐
- Cypress系列(16)- 查找页面元素的基本方法
如果想从头学起Cypress,可以看下面的系列文章哦 https://www.cnblogs.com/poloyy/category/1768839.html 前端页面代码 后面写的 Cypress ...
- 一文说通Dotnet Core的后台任务
这是一文说通系列的第二篇,里面有些内容会用到第一篇中间件的部分概念.如果需要,可以参看第一篇:一文说通Dotnet Core的中间件 一.前言 后台任务在一些特殊的应用场合,有相当的需求. 比方, ...
- 【百度前端学院 Day4】背景边框列表链接和更复杂的选择器
1. 背景 背景指的是元素内容.内边距和边界下层的区域(可用background-clip修改) background-color 背景色 background-image 背景图片(url) b ...
- 深入理解JVM(③)各种垃圾收集算法
前言 从如何判定对象消亡的角度出发,垃圾收集算法可以划分为"引用计数式垃圾收集"(Reference Counting GC)和"追踪式垃圾收集"(Tracin ...
- 增值税发票税控开票软件助手Excel、ERP、SAP导入开票接口进行批量开票操作手册
写这遍文章的目的是方便以后个人使用,做个笔记记录. 首先我来说一下它是做什么用的,它的主要作用是把用户的开票数据,Excel数据.ERP 系统.SAP导入到增值税发票税控开票软件中,可用航信盘.百旺盘 ...
- 记录一次Flink作业异常的排查过程
最近2周开始接手apache flink全链路监控数据的作业,包括指标统计,业务规则匹配等逻辑,计算结果实时写入elasticsearch. 昨天遇到生产环境有作业无法正常重启的问题,我负责对这个问题 ...
- 深入理解Java虚拟机学习笔记(三)-----类文件结构/虚拟机类加载机制
第6章 类文件结构 1. 无关性 各种不同平台的虚拟机与所有平台都统一使用的程序存储格式——字节码(即扩展名为 .class 的文件) 是构成平台无关性的基石. 字节码(即扩展名为 .class 的文 ...
- Windows 程序设计(3) 关于字符串
1. 宽窄字节的区别及重要性 1.1 宽窄字节简介: C语言/C++语言,使用的字符串指针就是 char* 类型,C++中的字符串是 string,内部也是对 char* 的封装 窄字节 其实最早的系 ...
- cb24a_c++_STL算法简介
算法概述 算法部分主要由头文件<algorithm>,<numeric>和<functional>组成. <algorithm>是所有STL ...
- SQLserver 的分页存储过程
-- 1.建立修改学生数据的存储过程 -- 2.建立根据班级Id和学生姓名模糊查询的分页存储过程,要求正确输出总记录数,总页数-- (输入班学生姓名 计算总记录数 计算总页数) -- @name ...