关于基环树找环问题

                                   关于基环树的环可以使用拓扑排序来解决

在基环树中,只有唯一的环在拓扑排序后入度任然为2。所以使用拓扑排序来标记,未被标记的点就是环上的点。

P8655 [蓝桥杯 2017 国 B] 发现环 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

​
#include "bits/stdc++.h"
using namespace std;

#define int long long 
#define endl '\n'
#define IOS ios::sync_with_stdio(0),cin.tie(0);
#define all(x) x.begin(),x.end()
#define pi pair<int,int> 
#define vi vector<int>
#define si set<int> 
#define mi map<int,int>
#define mc map<char,int>
#define YES cout<<"Yes"<<endl;
#define NO  cout<<"No"<<endl;
#define pb(x) push_back(x);
#define fi first
#define sc second
#define is insert
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return true; } return false; }
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return true; } return false; }
const int INF =1e18;
const int N = 1e5+10;
int in[N],st[N];
vector<int> v[N];
int n;
void top()
{
	queue<int> q;
	for (int i=1;i<=n;i++){
		if(in[i]==1){
			q.push(i);
			st[i]=1;
		}
		
		while(q.size()){
			int tmp=q.front();
			q.pop();
			
			for (auto it : v[tmp]){
				in[it]--;
				if(in[it]==1){
					q.push(it);
					st[it]=1;
					
				}
			}
			
		}
	}
}

void print()
{
	for (int i=1;i<=n;i++){
		if(!st[i]){
			cout<<i<<" ";
		}
	}	
}
signed main()
{
	IOS
	//.........................//

	cin>>n;
	//memset(h,-1,sizeof h);
	for (int i=1;i<=n;i++){
		int x,y;
		cin>>x>>y;
		v[x].pb(y);
		v[y].pb(x);
		in[x]++;
		in[y]++;
	}
	
	top();
	print();

	//return 1;
}

​

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
c,可以使用深度优先搜索(DFS)算法来实现。以下是使用vector存储图的一个示例代码: ```cpp #include <iostream> #include <vector> using namespace std; vector<bool> visited; // 记录节点是否已经访问过 vector<int> parent; // 记录每个节点的父节点 vector<bool> inCycle; // 记录节点是否在中 vector<int> cycle; // 存储到的 // 深度优先搜索 bool dfs(vector<vector<int>>& graph, int node, int parentNode) { visited[node] = true; parent[node] = parentNode; for (int neighbor : graph[node]) { if (!visited[neighbor]) { if (dfs(graph, neighbor, node)) return true; } else if (neighbor != parentNode) { // 到了 cycle.push_back(neighbor); inCycle[neighbor] = true; int cur = node; while (cur != neighbor) { cycle.push_back(cur); inCycle[cur] = true; cur = parent[cur]; } cycle.push_back(neighbor); // 将最后一个节点加入中 return true; } } return false; } // c vector<int> findCycle(vector<vector<int>>& graph) { int n = graph.size(); visited.resize(n, false); parent.resize(n, -1); inCycle.resize(n, false); for (int i = 0; i < n; i++) { if (!visited[i] && dfs(graph, i, -1)) break; } return cycle; } int main() { int n = 4; // 图的节点数 vector<vector<int>> graph(n); // 添加图的边 graph[0].push_back(1); graph[1].push_back(0); graph[1].push_back(2); graph[2].push_back(1); graph[2].push_back(3); graph[3].push_back(2); vector<int> cycle = findCycle(graph); // 输出c中的节点 cout << "c中的节点: "; for (int node : cycle) { cout << node << " "; } cout << endl; return 0; } ``` 以上代码通过深度优先搜索遍历图,当遇到一个已经访问过的节点时,如果该节点不是当前节点的父节点,则到了一个。然后通过记录每个节点的父节点,可以回溯到构成该的所有节点。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值