图综合练习--构建邻接表

Description

已知一有向图,构建该图对应的邻接表。

邻接表包含数组和单链表两种数据结构,其中每个数组元素也是单链表的头结点,数组元素包含两个属性,属性一是顶点编号info,属性二是指针域next指向与它相连的顶点信息。

单链表的每个结点也包含两个属性,属性一是顶点在数组的位置下标,属性二是指针域next指向下一个结点。

Input

第1行输入整数t,表示有t个图

第2行输入n和k,表示该图有n个顶点和k条弧。

第3行输入n个顶点。

第4行起输入k条弧的起点和终点,连续输入k行

以此类推输入下一个图

Output

输出每个图的邻接表,每行输出格式:数组下标 顶点编号-连接顶点下标-……-^,数组下标从0开始。

具体格式请参考样例数据,每行最后加入“^”表示NULL。

Input

Copy

1
5 7
A B C D E
A B
A D
A E
B D
C B
C E
E D
Output

Copy

0 A-1-3-4-^
1 B-3-^
2 C-1-4-^
3 D-^
4 E-3-^

想法

这样子的就是邻接表,其实可以用一个二维的vector实现,只要你记得那一行,0位是起始点,后面的都是终点。

而我的想法是用一个结构体,然后里面存着一个起点,和一个全是终点的数组。

我的处理

因为这道题是字符表示点,所以ch就是起始点的字符,然后edge里面存的都是终点的点

这道题要的是输出起始点的字符,下标,还有终点的下标

我的写法画出来的图就是这样,举出第一个例子

A的下标是0,代表起始点的下标是0,

然后里面的数组有1,3,4

意思是0-1,0-3,0-4.可以看成A-B,A-D,A-E

然后我输出的时候取0,然后取0位置的字符,然后取edge里面数组的所有元素就是1,3,4;

而且要是需要输出终点的字符的话,edge里面元素是不是也对应着link里面的字符,就像1对应B

实现代码如下:

#include <iostream>
#include <cstdio>
#include <vector>
#include <map>
using namespace std;
map<char, int>p;///这里为什么要用map是因为我输入的边是两个点
///然后两个点得是字符,然后我要用数组把他们存起来那我就需要有int的下标
struct link///写了个链表
{
    char ch;
    vector<int>edge;///一个链表里面有多个数组,就是有多条边
    //比如这个是0,然后edge里面存了1,2,3,4,那意思就是0-1,0-2,0-3,0-4有条边
};

int main()
{
    int t;
    cin >> t;
    while (t--)
    {
        link* ss;///这里用指针主要我想这总共开始有多少个点就需要多少个数组,new就好了
        int n, m;
        cin >> n >> m;///输入有n个点,m条边
        ss = new link[n];///说明有5个起始点,就是出发的点
        for (int i = 0; i < n; i++)///输入点,并且用map存储对应下标
        {
            char ch;
            cin >> ch;///输入字符
            p[ch] = i;///第一个字符的下标就是0
            ss[i].ch = ch;///第一个链的起始点就是字符ch
        }
        for (int i = 0; i < m; i++)
        {
            char a, b;///连接两个点输入的是字符
            cin >> a >> b;
            ss[p[a]].edge.push_back(p[b]);///所以有点类似二维数组,我们要找到这个字符的下标就是数字才能知道要在哪里添加一条边
        }
        for (int i = 0; i < n; i++)
        {
            cout << i << " " << ss[i].ch;///输出起始点
            int len = ss[i].edge.size();
            for (int j = 0; j < len; j++)
            {
                cout << "-" << ss[i].edge[j];///输出终点
            }
            cout << "-^" << endl;
        }
        p.clear();
        delete[]ss;
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值