一千题,No0006(图的存储)

输出给定图的邻接表。

输入格式:

输入第一行给出三个正整数,分别表示无向图的节点数N(1<N≤10)、边数M(≤50)和有向或无向标志S(1表示有向图,0表示无向图)。
随后的M行对应M条边,每行给出一对正整数,分别是该条边直接连通的两个节点的编号(编号范围1~N)。

输出格式:

输出图的邻接表,从第0行开始按顺序输出,共输出N行,具体样式见输出样例。冒号前后无空格,每个元素间有一个空格,末尾均有一空格。
由于图的存储是不唯一的,为了使得输出具有唯一的结果,我们约定以表头插入法构造邻接表。

输入样例:

6 8 0 
1 2
2 3 
3 4 
4 5 
5 6 
6 4 
3 6 
1 5

输出样例:

0:4 1 
1:2 0 
2:5 3 1 
3:5 4 2 
4:0 5 3 
5:2 3 4 

 解题思路:

邻接表:

邻接表是一个数组[链表],数组上有图中所有出现的点,并且数组每个点都伸出一条链表存储可以直接到达的节点(没有顺序),可以直接看作一个vector;

c++代码如下:

#include <bits/stdc++.h>

#define elemtype int
using namespace std;

struct point//模拟链表节点
{
    void print_data()//输出所有点
    {
        if(_data.empty())
        {
            return;
        }
        for(auto &elem : _data)
        {
            cout << elem << " ";
        }
        cout << endl;
    }
    deque<elemtype> _data;
};

struct Graph//存储链表数组
{
    deque<point> _point;
};

int main()
{
    int point_num,side_num,n;
    cin >> point_num >> side_num >> n;

    //初始化
    Graph grp;
    for(int i = 0;i < point_num;++i)
    {
        point p;
        grp._point.push_back(p);
    }

    //循环存储
    while(side_num--)
    {
        int x,y;
        cin >> x >> y;
        grp._point[x-1]._data.push_front(y-1);
        if(n == 0)
        {
            grp._point[y-1]._data.push_front(x-1);
        }
    }

    //输出
    int num = 0;
    for(auto &elem : grp._point)
    {
        cout << num++ << ":";
        elem.print_data();
    }
    return 0;
}

邻接矩阵:

如图所示:

 将1代表有路0代表没路;若果是有权图则1用权重表示,0表示为本节点,用无穷表示没路

特别的:无向图时对称的,有向图不一定是

代码将上一个稍微改一下即可

c++代码如下:

#include <bits/stdc++.h>

#define elemtype int
using namespace std;

struct point//模拟链表节点
{
    void print_data()//输出所有点
    {
        if(_data.empty())
        {
            return;
        }
        for(auto &elem : _data)
        {
            cout << elem << " ";
        }
        cout << endl;
    }
    deque<elemtype> _data;
};

struct Graph//存储链表数组
{
    deque<point> _point;
};

int main()
{
    int point_num,side_num,n;
    cin >> point_num >> side_num >> n;

    //初始化
    Graph grp;
    for(int i = 0;i < point_num;++i)
    {
        point p;
        int times = point_num;
        while(times--)
        {
            p._data.push_front(0);
        }
        grp._point.push_back(p);
    }

    //循环存储
    while(side_num--)
    {
        int x,y;
        cin >> x >> y;
        grp._point[x-1]._data[y-1] = 1;
        if(n == 0)
        {
            grp._point[y-1]._data[x-1] = 1;
        }
    }

    //输出
    int num = 0;
    for(auto &elem : grp._point)
    {
        elem.print_data();
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值