关于树和图存储的特别方法

链式前向星

关键代码:

const int N = 1e+5;
int h[2*N], e[2*N], ne[2*N], idx;
//h存的是所以与节点x相连的边构成的链的头结点,是每个节点在e/ne数组中对应的idx
//e存时的节点元素x,ne存的是对应的e的相邻节点,idx是一个指针
bool vis[N];
void add(int x, int y)
//这一块操作类似链表节点的插入,我在写散列表里面有详细解释,操作相当于头插法
{
    
    
	e[idx] = y;
	ne[idx] = h[x];
	h[x] = idx++;
}
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 1e+5;
//开二维数组空间太大了,不可行,采用链式存储,一般的链式存储写起来又麻烦,所以采用前向星
int h[2*N], e[2*N], ne[2*N], idx;
bool vis[N];
void add(int x, int y)
{
    
    
	e[idx] = y;
	ne[idx] = h[x];
	h[x] = idx++;
}
void dfs(int x)
{
    
    
	vis[x] = true;//判断当前节点是否被访问过
	cout << x << " ";
	for (int i = h[x]; i != -1; i = ne[i])
	//i=h[e[x]]是直接让i指向e[x]的邻边构成的链,i=ne[i]是链上节点在e/ne中的idx
		if (!vis[e[i]]) dfs(e[i]);
}
int main()
{
    
    
	int n, x, y;
	memset(h, -1, sizeof h);
	cin >> n;
	for (int i = 0; i < n - 1; i++)
	{
    
    
		cin >> x >> y;
		add(x, y), add(y, x);
	}
	dfs(0);
	return 0;
}

采用vector存储

例题–鬼谷八荒

#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
const int N = 1e4 + 5;
int rak[N],vis[N];
vector<int>V[N];
int main()
{
    
    
	int n, m, x, y;
	cin >> n >> m;
	for (int i = 0; i < m; i++)
	{
    
    
		cin >> x >> y;
		V[x].push_back(y); V[y].push_back(x);//存节点直接的关系
	}
	queue<int>q;
	q.push(1); vis[1] = 1; rak[1] = 1;
	vector<int>temp[N];
	temp[1].push_back(1);
	while (!q.empty())
	{
    
    
		int point = q.front();
		for(int i=0;i<V[point].size();i++)
			if (!vis[V[point][i]])
			{
    
    
				vis[V[point][i]] = 1;
				rak[V[point][i]] = rak[point] + 1;
				temp[rak[V[point][i]]].push_back(V[point][i]);
				q.push(V[point][i]);
			}
		q.pop();
	}
	for (int i = 1; i <= n; i++) 
		if (rak[i] == 0) {
    
    
			cout << -1<<" ";
			return 0;
		}

	for (int i = 1; temp[i].size() != 0; i++)
	{
    
    
		sort(temp[i].begin(), temp[i].end());
		for (auto x : temp[i]) cout << x << " ";
		cout << endl;
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_50816938/article/details/119145776
今日推荐