B. Fish Graph(dfs找环)

news/2024/7/20 20:07:20 标签: 深度优先, 算法

Problem - 1817B - Codeforces

给定一个具有n个节点和m条边的简单无向图。请注意,该图不一定是连通的。节点从1到n标记。

如果图包含具有特殊节点u的简单循环,则定义图为Fish Graph。除循环中的边之外,图应恰好有2条额外的边。两条边都应连接到节点u,但它们不应连接到循环的任何其他节点。

确定图是否包含子图,其中包含Fish图,并且如果是这样,请找到任何此类子图。

在本问题中,我们将子图定义为通过取原始图的任意边集获得的图像。

输入:

第一行输入整数t(1≤t≤1000),表示测试用例数量。接下来是测试用例的描述。

每个测试用例的第一行包含两个整数n和m(1≤n,m≤2000)——节点数和边数。

接下来的m行中的每一行都包含一条边的描述。每行包含两个整数ui和vi(1≤ui,vi≤n,ui≠vi)——一条边连接节点ui到节点vi。

保证没有两条边连接相同的无序节点对。

此外,保证所有测试用例的n总和和m总和均不超过2000。

输出:

对于每个测试用例,如果图包含子图,则输出“YES”,其为Fish图,否则打印“NO”。如果答案是“YES”,则在以下行中输出子图的说明。

说明的第一行包含一个整数k——子图的边数。

在接下来的k行中,输出所选子图的边缘。每个k行都应包含两个整数u和v(1≤u,v≤n,u≠v)——连接u和v的边属于子图。打印u和v的顺序无所谓,只要两个节点由原始图中的一条边连接即可。无论如何打印边缘的顺序都没有关系,只要结果子图是Fish Graph。

如果有多个解决方案,请打印任何一个。

示例:

Example

Input

Copy

 

3

7 8

1 2

2 3

3 4

4 1

4 5

4 6

4 2

6 7

7 7

6 7

1 2

2 3

3 4

4 1

1 3

3 5

4 4

1 3

3 4

4 1

1 2

Output

Copy

YES
6
5 4
6 4
4 3
1 4
2 1
3 2
YES
5
5 3
2 3
3 1
4 3
1 4
NO

 题解:
如果有这样的子图,其中一个点度数一定>= 4,一个环上的点外连两条枝干,即使这两条枝干也属于一个环,也没问题,因为我们找的是子图,只要拿特定的边即可

因此我们只需要搜索每个度数>=4的点,看他是否有环,有环就一定是

具体细节代码中都有注释

#include <cstdio>
#include <cstring>
#include <algorithm>
#include<iostream>
#include<vector>
#include<set>
#include<map>
#include<cmath>
#include<queue>
using namespace std;
typedef long long ll;
 #define int long long
typedef pair<int,int> PII;
typedef unsigned long long ULL;
const int N = 4e5 + 10;
int mod = 1e9 + 7;
vector<int> p[N];
vector<int> ans;
int st[N];//看当前点是否走过
int vis[N];//标记目标节点相邻的节点
int dfs(int u,int f)
{
	if(st[u])
	return 0;
	ans.push_back(u);//存点
	st[u] = 1;
	if(vis[u]&&u != f)
	return 1;//如果碰到了,与目标节点相邻的节点,并且不是我们最开始的搜索起点,说明存在环
	for(auto ne:p[u])
	{
		if(dfs(ne,f))
		return 1;
	}
	ans.pop_back();//如果无环清空
	return 0;
}
void solve()
{
	int n,m;
	cin >> n >> m;
	for(int i = 1;i <= m;i++)
	{
		int x,y;
		cin >> x >> y;
		p[x].push_back(y);
		p[y].push_back(x);
	}
	int f = 0;
	ans.clear();
	for(int i = 1;i <= n;i++)
	{
		if(p[i].size() < 4)
		continue;
		for(int j = 1;j <= n;j++)
		{
			st[j] = 0;
			vis[j] = 0;
		}
		st[i] = 1;
		for(auto ne:p[i])
		{
			vis[ne] = 1;
		}
		for(auto ne:p[i])
		{
			if(dfs(ne,ne))
			{
				f = i;
				break;
			}
		}
		if(f)
		break;
	}
	if(f)
	{
		cout <<"YES\n";
		cout << ans.size() + 3 <<"\n";
		cout << f <<" "<<ans[0] <<"\n";
		cout << f <<" "<<ans[ans.size() - 1] <<"\n";
		for(int i = 0;i < ans.size() - 1;i++)
		cout << ans[i] <<" " << ans[i + 1] <<"\n";
		int c = 0;
		for(auto ne:p[f])
		{
			if(c == 2)
			break;
			if(ne != ans[0]&&ne != ans[ans.size() - 1])
			{
				cout <<f <<" " <<ne <<"\n";
				c++;
			}
		}
	}
	else
	{
		cout <<"NO\n";
	}
	
	for(int i = 1;i <= n;i++)
	{
		p[i].clear();
	}
}
signed main()
{
	ios::sync_with_stdio(0 );
	cin.tie(0);cout.tie(0);
	int t = 1;
	cin >> t;
	while(t--)
	{
		solve(); 
	}
}


http://www.niftyadmin.cn/n/463055.html

相关文章

Qt-自定义控件

Qt-自定义控件 简单使用 首先创建一个工程 在现有的工程上添加文件&#xff0c;选择Qt设计师界面类 选择Widget 添加两个控件之后&#xff0c;选择水平布局 将刚刚自定义的控件smallWidget放置在原始的控件中 首先在原始工程的ui界面 随便放置一个widget 选择&#xff…

Three.js教程:阵列立方体和相机适配体验

推荐&#xff1a;将NSDT场景编辑器加入你的3D工具链 其他系列工具&#xff1a;NSDT简石数字孪生 阵列立方体和相机适配体验 本节课通过阵列一片立方体&#xff0c;进一步体验下透视投影相机的投影规律。 for循环创建一列模型 const geometry new THREE.BoxGeometry(100, …

指针与数组--动态数组(2)[1、长度可变的一维动态数组 2、长度可变的二维动态数组]

目录 一、长度可变的一维动态数组 二、长度可变的二维动态数组 由上篇文章的理论&#xff0c;接下来使用例题来阐述。 一、长度可变的一维动态数组 例题1、编程输入某班学生的某门课成绩&#xff0c;计算并输出平均值。学生人数由键盘输入。 #include <stdio.h> #i…

安科瑞产品在泛在电力物联网的应用

安科瑞虞佳豪 泛在电力物联网是以通讯技术为基础发展而来的新型物联网体系&#xff0c;其构建的核心是满足电网能源系统的智能判断和自适应调节能力&#xff0c;这将提高能源的替代和利用能力。对于电力物联网来说&#xff0c;通讯技术是其核心的技术内容之一&#xff0c;也是…

中国电子学会2023年05月份青少年软件编程C++等级考试试卷三级真题(含答案)

1.找和为K的两个元素 在一个长度为n(n < 1000)的整数序列中&#xff0c;判断是否存在某两个元素之和为k。 【输入】 第一行输入序列的长度n和k&#xff0c;用空格分开。 第二行输入序列中的n个整数&#xff0c;用空格分开。 【输出】 如果存在某两个元素的和为k&#xff0c…

表上作业法一般流程(最小元素法、闭合回路法、位势法)

目录 一、列出物资调运平衡表和运价表 二、编制初始调运方案 三、初始方案的检验与调整 1&#xff09;闭合回路法 2&#xff09;位势法 3&#xff09;调整调运方案 表上作业法一般步骤&#xff1a; ①列出调运物资的供需(产销)平衡表及运价表&#xff1b; ②按最小元素…

文心一言 VS 讯飞星火 VS chatgpt (46)-- 算法导论6.1 4题

四、假设一个最大堆的所有元素都不相同&#xff0c;那么该堆的最小元素应该位于哪里? 文心一言&#xff1a; 最大堆的最小元素位于堆的根结点。由于最大堆的性质&#xff0c;根结点是堆中所有元素的最大值&#xff0c;因此它也是堆中所有元素的最小值。 讯飞星火&#xff1a…

Java——基础语法

文章目录 1. 变量&#xff1a;变量的声明和初始化变量的作用域变量的命名规则常量 2. 运算符&#xff1a;算术运算符关系运算符逻辑运算符位运算符其他运算符 3. 流程控制&#xff1a;分支结构循环结构跳转控制 4. 类与对象&#xff1a;类的概念对象的概念类的成员构造方法和析…