基环树

基环树

简单无向图有n个点n-1条边,那么它们会连成一条直线

n个点n条边,相对多一条边,有且仅有一个环

可以利用拓扑排序找这个环

例题:F - Well-defined Path Queries on a Namori

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 2e5 + 10,MAXM = 2e5 + 10;
int n,q;
struct edge{
	int v;
	edge* nex;
}ed[MAXM * 2];
edge* head[MAXN];
int ptop = 0;
void add(int u,int v)
{
	ed[ptop].v = v;
	ed[ptop].nex = head[u];
	head[u] = &ed[ptop];
	ptop++;
}
int du[MAXN];
bool unable[MAXN];
int co = 1;//颜色
int color[MAXN];
void tp()//拓扑排序,找环
{
	queue<int> qu;
	for(int i = 1;i <= n;i++)
		if(du[i] == 1)
			qu.push(i);
	while(!qu.empty())
	{
		int u = qu.front();qu.pop();
		unable[u] = 1;
		edge* p = head[u];
		while(p != NULL)
		{
			int v = p -> v;
			du[v]--;
			if(du[v] == 1)
				qu.push(v);
			p = p -> nex;
		}
	}
}
bool use[MAXN];
void dfs(int c,int p)//染色
{
	if(use[p] || !unable[p])
		return;
	use[p] = 1;
	color[p] = c;
	edge* pp = head[p];
	while(pp != NULL)
	{
		int v = pp -> v;
		dfs(c,v);
		pp = pp -> nex;
	}
}
int main()
{
	cin >> n;
	for(int i = 1;i <= n;i++)
	{
		int u,v;cin >> u >> v;
		du[u]++,du[v]++;
		add(u,v);
		add(v,u);
	}
	tp();
	for(int i = 1;i <= n;i++)
	{
		if(!unable[i])
		{
			color[i] = co;
			edge* p = head[i];
			while(p != NULL)
			{
				int v = p -> v;
				dfs(co,v);
				p = p -> nex;
			}
			co++;
		}
	}
	cin >> q;
	while(q--)
	{
		int u,v;cin >> u >> v;
		if(color[u] == color[v])
			cout << "Yes" << endl;
		else
			cout << "No" << endl;
	}
}
posted @   xxcdsg  阅读(18)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
点击右上角即可分享
微信分享提示