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;
}
}