基环树
简单无向图有n个点n-1条边,那么它们会连成一条直线
n个点n条边,相对多一条边,有且仅有一个环
可以利用拓扑排序找这个环
#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;
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效