啊哈算法(5)——图的遍历

图的深度优先遍历和广度优先遍历
1、深度优先遍历

#include<iostream>

using namespace std;


int e[101][101];//使用邻接矩阵来存储一个图
int book[101];
int sum, n;

void dfs(int pos)
{
    cout << pos << " ";
    sum++;
    if (sum == n)
        return;
    for (int i = 1; i <= n; ++i)
    {
        if (e[pos][i] == 1 && book[i] == 0)
        {
            book[i] = 1;
            dfs(i);
        }
    }
}
int main()
{
    cin >> n;//图中节点的个数
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= n; ++j)
            if (i == j)
                e[i][j] = 0;            
            else
                e[i][j] = INT_MAX;        //没有边连接的记为最大


    int a, b;
    for (int i = 1; i <= n; ++i)
    {
        cin >> a >> b;
        e[a][b] = 1;
        e[b][a] = 1;     //由于为无向图 所以双向的
    }
    book[1] = 1;
    dfs(1);
    system("pause");
}

2、广度优先遍历

#include<iostream>

using namespace std;


int e[101][101];//使用邻接矩阵来存储一个图
int book[101];
int sum, n;
int que[10001];
int main()
{
    cin >> n;//图中节点的个数
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= n; ++j)
            if (i == j)
                e[i][j] = 0;
            else
                e[i][j] = INT_MAX;


    int a, b;
    for (int i = 1; i <= n; ++i)
    {
        cin >> a >> b;
        e[a][b] = 1;
        e[b][a] = 1;     //由于为无向图 所以双向的
    }
    int head=1, tail=1;
    que[head] = 1;
    book[1] = 1;
    tail++;
    while (head<tail)
    {
        int pos = que[head];
        cout << pos << " ";
        for (int i = 1; i <= n; ++i)
        {
            if (e[pos][i] == 1 && book[i] == 0)
            {
                book[i] = 1;
                que[tail] = i;
                tail++;
            }
        }
        head++;
    }
    system("pause");
}

图遍历的应用
例1:城市地图,第一行给出n个城市(城市编号1~n),和m条公路。接下来每一行类似“a b c”这样的数据,表示有一条路可以从城市a到城市b,并且路程为c公里。公路都是单向的,求1到n的最短路径。

#include<iostream>

using namespace std;


int e[101][101];//使用邻接矩阵来存储一个图
int book[101];
int sum, n,m,min=INT_MAX;

void dfs(int pos, int dis)
{
    if (dis > min)
        return;
    if (pos == n)
    {
        min = dis;
        return;
    }   
    for (int i = 1; i <= n; ++i)
    {
        if (e[pos][i] != INT_MAX&&book[i] == 0)
        {
            book[i] = 1;
            dfs(i, dis + e[pos][i]);
            book[i] = 0;
        }
    }
}
int main()
{
    cin >> n>>m;//图中节点的个数
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= n; ++j)
            if (i == j)
                e[i][j] = 0;
            else
                e[i][j] = INT_MAX;


    int a, b,c;
    for (int i = 1; i <= m; ++i)
    {
        cin >> a >> b>>c;
        e[a][b] = c;
        //e[b][a] = c;     //由于为无向图 所以双向的
    }

    book[1] = 1;
    dfs(1, 0);
    cout << min << endl;
    system("pause");
}

例2:最少转机,第一行给出n个城市(城市编号1~n),和m条航线。以及起点城市a,和目标城市 ,接下来的m行表示两个城市之间可达,求最少的从起点城市到目标城市最少的转机次数。

#include<iostream>

using namespace std;

int e[101][101];  //用来存储地图
int book[101];    //标记

struct note
{
    int x;//城市编号
    int s;//转机数目
};
int main()
{
    struct note que[10001];//扩展队列 地图大小100*100
    int flag = 0;//用来标记到达目标城市
    int n, m, start, end;
    cin >> n >> m;
    cin >> start >> end;
    for (int i = 1; i <= n; ++i)
    {
        for (int j = 1; j <= n; ++j)
        {
            if (i == j)
                e[i][j] = 0;
            else
                e[i][j] = INT_MAX;
        }
    }

    int a, b;
    for (int i = 1; i <= m; ++i)
    {
        cin >> a >> b;
        e[a][b] = 1;
        e[b][a] = 1;
    }

    int head = 1, tail = 1;
    que[tail].x = start;
    que[tail].s = 0;
    tail++;
    book[start] = 1;
    while (head<tail)
    {
        int cur = que[head].x;
        for (int i = 1; i <= n; ++i)
        {
            if (e[cur][i] == 1 && book[i] == 0)
            {
                que[tail].x = i;
                que[tail].s = que[head].s + 1;
                tail++;
                book[i] = 1;
            }

            if (que[tail-1].x == end)
            {
                flag = 1;
                break;
            }
        }
        if (flag == 1)
            break;
        head++;
    }
    cout << que[tail - 1].s << endl;
    system("pause");
}

note:当然这里也可以使用DFS,但是对于权值相同的情况,使用BFS更快

猜你喜欢

转载自blog.csdn.net/xc13212777631/article/details/82018016