给定n个结点m条边的简单无向图,判断该图是否存在鱼形状的子图:有一个环,其中有一个结点有另外两条边,连向不在环内的两个结点。若有,输出子图的连边

题目

思路:

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define pb push_back
#define fi first
#define se second
#define lson p << 1
#define rson p << 1 | 1
const int maxn = 1e6 + 5, inf = 1e18 * 3, maxm = 4e4 + 5, mod = 1e9 + 7;
int a[maxn], b[maxn];
int n, m;
string s;
bool vis[maxn];
vector<int> G[maxn];
int from, to;
vector<int> tmp, vec;
int deg[maxn];

void dfs(int u, int p){
	if(u == to && p == from) return;
	if(vis[u]) return;
	vis[u] = 1;
	tmp.pb(u);
	if(u == to){
		vec = tmp;
		return;
	}
	for(auto v : G[u]){
		dfs(v, u);
	}
	tmp.pop_back();
}
void solve(){
    int res = 0;
    int k, x, q;
	cin >> n >> m;
	for(int i = 1; i <= n; i++){
		G[i].clear();
		deg[i] = 0;
	}
	for(int i = 1; i <= m; i++){
		int u, v;
		cin >> u >> v;
		G[u].pb(v);
		G[v].pb(u);
		deg[u]++;
		deg[v]++;
	}
	for(int u = 1; u <= n; u++){
		if(deg[u] < 4) continue;
		for(auto v : G[u]){
			for(int i = 1; i <= n; i++){
				vis[i] = 0;
			}
			from = u;
			to = v;
			vec.clear();
			tmp.clear();
			dfs(u, u);
			if(vec.empty()) continue;
			vector<int> extra;
			tmp.clear();
			for(auto x : G[u]){
				if(x == vec.back() || x == *(vec.begin() + 1)) continue;
				if(find(vec.begin(), vec.end(), x) == vec.end()){//不在环内
					extra.pb(x);
					if(extra.size() == 2) break;
				}
				else{
					tmp.pb(x);//在环内,且与u相连
				}
			}
			vector<int> vt;
			if(extra.size() < 2){
				for(auto x : vec){
					vt.pb(x);
					if(find(tmp.begin(), tmp.end(), x) != tmp.end()){//在tmp内
						break;
					}
				}
				
				extra.pb(vec.back());
				for(int i = vec.size() - 1; i >= 0; i--){
					int x = vec[i];
					if(find(tmp.begin(), tmp.end(), x) != tmp.end()){
						extra.pb(x);
						break;
					}
				}
				// extra.pb(vec.end() - 2) 不能这样写,因为这个结点不一定与u相连
				// extra.pb(tmp.back()); 不能这样写,因为tmp的顺序跟环的结点顺序不一致

				extra.resize(2);
				vec = vt;
			}
			cout << "Yes\n";
			cout << vec.size() + 2 << '\n';
			int m = vec.size();
			for(int i = 0; i < vec.size(); i++){
				cout << vec[i] << ' ' << vec[(i + 1) % m] << '\n';
			}
			cout << u << ' ' << extra[0] << '\n';
			cout << u << ' ' << extra[1] << '\n';
			return;
		}
		
	}
	cout << "No\n";
}
    
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    int T = 1;
    cin >> T;
    while (T--)
    {
        solve();
    }
    return 0;
}
相关推荐
m0_720245014 小时前
1543.统计好三元组(简单)
开发语言·算法
To_OC4 小时前
LC 560 和为 K 的子数组:前缀和配哈希表,这对组合我是真的服了
javascript·算法·程序员
hans汉斯5 小时前
《软件工程与应用》期刊推荐&10月版面征稿中
图像处理·人工智能·深度学习·算法·音视频·软件工程
叠层归一研究院5 小时前
AGI 系统(八):符号范畴嵌入函子 — SymCat ↪ C_M107 严格化
c语言·开发语言·人工智能·算法·transformer·agi
其美杰布-富贵-李6 小时前
08 进阶评估指标与算法特定指标
人工智能·算法
.道阻且长.6 小时前
5.LeetCode算法习题讲解--双指针--有效三角形的个数
算法·leetcode·职场和发展
我是海飞7 小时前
杰理JL703N SSD1306 OLED(128x64) 点阵屏移植说明
单片机·算法·嵌入式·音频·杰理
wabs6668 小时前
关于图论【最短路径之Bellman_ford 算法(单源有限最短路)|卡码网96.城市间货物运输III的思考】
数据结构·算法·图论·卡码网·bellman_ford·单源有限最短路
lsylalalala10 小时前
常见的排序算法1
数据结构·算法·排序算法
想吃火锅100510 小时前
【leetcode】54. 螺旋矩阵
算法·leetcode·矩阵