当前位置: 首页 > news >正文

信息学奥赛一本通 1522:网络 | OpenJudge 百练 1144:Network

【题目链接】

ybt 1522:网络
OpenJudge 百练 1144:Network

【题目考点】

1. 图论:割点

【解题思路】

每个交换机是一个顶点,如果两地点之间有电话线连接,那么两顶点之间有一条无向边,该图是无向图。
初始时任何地点之间都是可以通讯的,也就是说这是一个无向连通图。
如果一个交换机停止工作,导致其它一些地点不能通讯,这样的地点交灾区。那么也就是图中去掉该顶点后,有些顶点之间不再连通(没有路径),那么也就是整个图不再是连通图。这样的点就是割点。
灾区就是割点,统计灾区的数量就是统计割点的数量。
使用tarjan算法求出所有割点,将割点保存在一个set中,或用数组标记哪些顶点是割点,而后统计割点数量。

【题解代码】

解法1:Tarjan算法求割点,使用set保存割点
#include <bits/stdc++.h>
using namespace std;
#define N 105
int n, m;
vector<int> edge[N];//edge[i]:顶点i的邻接点 
int dfn[N], low[N], ts, root;
set<int> cutVer;
void tarjan(int u)
{
	int child = 0;
	dfn[u] = low[u] = ++ts;
	for(int v : edge[u])
	{
		if(dfn[v] == 0)
		{
			tarjan(v);
			low[u] = min(low[u], low[v]);
			if(u == root && ++child > 1 || u != root && dfn[u] <= low[v])
				cutVer.insert(u);
		}
		else
			low[u] = min(low[u], dfn[v]);
	} 
}
int main()
{
	int f, t;
	while(cin >> n && n != 0)
	{
		ts = 0;//变量初始化 
		for(int i = 1; i <= n; ++i)
			edge[i].clear();
		memset(dfn, 0, sizeof(dfn));
		cutVer.clear();
		while(cin >> f && f != 0)
			while(cin.get() != '\n')
			{
				cin >> t;
				edge[f].push_back(t);
				edge[t].push_back(f);
			}
		for(int v = 1; v <= n; ++v) if(dfn[v] == 0)
			tarjan(root = v);
		cout << cutVer.size() << endl;
	}
	return 0;
}
解法2:Tarjan算法求割点,使用标记数组保存割点
#include <bits/stdc++.h>
using namespace std;
#define N 105
int n, dfn[N], low[N], ts, root, ct;
vector<int> edge[N];
bool cutVer[N];//cutVer[i]:i是否是割点
void tarjan(int u)
{
	int child = 0;
	dfn[u] = low[u] = ++ts;
	for(int v : edge[u])
	{
		if(dfn[v] == 0)
		{
			tarjan(v);
			low[u] = min(low[u], low[v]);
			if(u == root && ++child > 1 || u != root && dfn[u] <= low[v])
				cutVer[u] = true;//u是割点 
		}
		else
			low[u] = min(low[u], dfn[v]); 
	}
} 
int main()
{
	int f, t;
	while(cin >> n && n != 0)
	{
		ts = ct = 0;//变量初始化 
		for(int i = 1; i <= n; ++i)
			edge[i].clear();
		memset(cutVer, 0, sizeof(cutVer));
		memset(dfn, 0, sizeof(dfn));
		while(cin >> f && f != 0)
			while(cin.get() != '\n')
			{
				cin >> t;
				edge[f].push_back(t);
				edge[t].push_back(f);
			}
		for(int v = 1; v <= n; ++v) if(dfn[v] == 0)
			tarjan(root = v);
		for(int v = 1; v <= n; ++v) if(cutVer[v])//统计割点数量 
			ct++;
		cout << ct << endl;
	}
	return 0;
}

相关文章:

  • 算法每日一练 (4)
  • 【Winform】深入理解C#中的异常处理:以WinForms应用程序为例
  • GB28181协议下的RTP传输
  • Android Loader机制解析
  • MapReduce 读取 Hive ORC ArrayIndexOutOfBoundsException: 1024 异常解决
  • Excell 代码处理
  • kafka基本知识
  • Prompt Engineering的重要性
  • JAVAweb-JS基本数据类型,变量,DOM,pop,push函数,事件
  • 【Python爬虫(47)】探秘分布式爬虫性能:从测试到优化之路
  • 哈希表入门到精通:从原理到 Python 实现全解析
  • 洛谷P9242 [蓝桥杯 2023 省 B] 接龙数列
  • 【SpringBoot教程】SpringBoot整合Caffeine本地缓存及Spring Cache注解的使用
  • SSI用量子计算来玩AI
  • 策略模式Spring框架下开发实例
  • AI(14)-prompt
  • 跟据spring boot版本,查看对应的tomcat,并查看可支持的tomcat的版本范围
  • Windows11安装GPU版本Pytorch2.6教程
  • [Android]文本多的时候让TextView的字体自动变小
  • 量子比特的实现与优化技术:解密量子计算的核心
  • 南京网站设计个人/帮平台做推广怎么赚钱
  • 建设工程规划许可证公示网站/seo学院
  • 网站导读怎么做/公司推广宣传文案
  • 香港网站空间价格/最新新闻热点素材
  • 杭州手机网站/长春网站关键词推广
  • 建站abc和凡科哪个好用/网络营销总监岗位职责