8648 图的深度遍历
时间限制:1000MS 代码长度限制:10KB
提交次数:1821 通过次数:1037
题型: 编程题 语言: G++;GCC
输入格式
第一行:输入0到3之间整数(有向图:0,有向网:1,无向图:2,无向网:3);
第二行:输入顶点数和边数;
第三行:输入各个顶点的值(字符型,长度〈3);(遍历从输入的第一个顶点开始)
第四行:输入每条弧(边)弧尾和弧头(以空格作为间隔),如果是网还要输入权值;
输出格式
输出对图深度遍历的结果。
输入样例
0
3 3
a b c
a b
b c
c b
输出样例
a b c
提示
注意题目的邻接表采用的是头插法,也就是后出现的边节点先被访问。
代码:
#include <iostream>
#include <vector>
using namespace std;
const int N = 100010;
vector<int> g[N]; // 邻接表表示图
int visited[N]={0}; // 标记每个节点是否已经被访问
int num = 1;//网的权值
int who;//判断有向/无向 图/网
int n, m;//点,边
char arr[1005];//第三行:输入各个顶点的值(字符型,长度〈3);(遍历从输入的第一个顶点开始)
int getp(char ch)//顶点序号
{
for (int i = 0;i < n;i++)
{
if (arr[i] == ch)return i;
}
// return 0;
}
// 图的深度优先搜索函数
void dfs(int u)
{
visited[u] = num++; // 标记节点u已经被访问
if (who == 0 || who==2) cout << arr[u] << ' '; // 输出当前正在访问的节点编号
else cout << arr[u] << ' ' << visited[u];//网要输出权值
// 递归地去访问每个与u相邻且未被访问的节点v
for (int i = 0; i < g[u].size(); i++)
{
int v = g[u][i];
if (!visited[v])
dfs(v);
}
}
int main()
{
cin >> who;
cin >> n >> m;
for (int i = 0;i < n;i++)cin >> arr[i];
// 读入边
char a, b;
while (m--)
{
cin >> a >> b;
//题目要求头插法,尾插法可以直接用push_back
if(who==0)g[getp(a)].insert(g[getp(a)].begin(),getp(b));//有向图
else if (who == 1)
{
g[getp(a)].insert(g[getp(a)].begin(),getp(b));//有向网
}
else if (who == 2)//无向图
{
g[getp(a)].insert(g[getp(a)].begin(), getp(b));
g[getp(b)].insert(g[getp(b)].begin(), getp(a)); // 无向图需要把反向边也加上
}
else//无向网
{
g[getp(a)].insert(g[getp(a)].begin(), getp(b));
g[getp(b)].insert(g[getp(b)].begin(), getp(a)); // 无向图需要把反向边也加上
}
}
// (遍历从输入的第一个顶点开始)
dfs(0);
return 0;
}
/*
a b c d
0 1 2 3
输入样例:
2
4 4
a b c d
a c
b d
a d
d c
a 0-3、2
b 1-3
c 2-3、0
d 3-2、0、1
遍历:从a开始即从0开始
0
/
3
/ \
2 1
即0 3 2 1
a d c b
*/