SCAU 8648 图的深度遍历

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
*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值