关于判定4种无向图的一些想法

回顾了这几道题之后,写一些总结。

  1. HDU 1198(求解 无向图 有几个 连通分量)
  2. HDU 1272(判断 无向图 是不是 无环连通图)
  3. HDU 1325(判断 有向图 是不是 树)

下面是无向图的四种情况:

无环连通图有环连通图无环非连通图(每一个连通分量都是无环的)有环非连通图(至少有一个连通分量是有环的)
边数 = 点数 - 1边数 > 点数 - 1边数 < 点数 - 1(点数 - 边数 = 连通分量数,且连通分量数 > 1)左边三种情况都有可能

从这个表格中可以看出以下两点:

  1. 若 边数 < 点数 - 1,则一定是非连通图。
  2. 若 边数 > 点数 - 1,则一定有环。
1. 求解无向图有几个连通分量

这个问题就是用并查集测试每一条边,看看conn最后是多少(上限为V.size()-1),因为conn相当于原图中所有连通分量各自的生成树的边数之和(原图的无环图版本,不改变原有的连通分量数),然后答案等于V.size()-conn

for (int i = 0; i < E.size(); i++)
{
	if (u(E[i].n1, E[i].n2))
		conn++;
	if (conn == V.size() - 1) break;
}
printf("%d\n", V.size() - conn);
2. 判断无向图有没有环

首先,若 边数 > 点数 - 1,则一定有环。
然后还是用并查集测试每一条边,只要u()返回falsef(n1)==f(n2))就说明有环。

if (E.size() > V.size() - 1 && !V.empty())
{
	printf("有环\n");
	return;
}
for (int i = 0; i < E.size(); i++)
{
	if (!u(E[i].n1, E[i].n2))
	{
		printf("有环\n");
		return;
	}
}
printf("无环\n");
return;
3. 判定 4 种无向图

判断 有环连通图 不能用flag,因为有可能边表的前V.size()-1条边都conn++了。

bool flag = false;
for (int i = 0; i < E.size(); i++)
{
	if (!u(E[i].n1, E[i].n2))
		flag = true;
	else conn++;
	if (conn == V.size() - 1) break;
}
if (conn == V.size() - 1)
{
	if (E.size() == V.size() - 1)
		printf("无环连通图\n");
	else printf("有环连通图\n");
}
else
{
	if (flag) printf("有环非连通图\n");
	else printf("无环非连通图\n");
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值