链式前向星
关键代码:
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;
}