acm,不知道还要不要继续,我希望,学习算法这条路不会断....
很早之前就想搞一个邻接表,怕自己忘记,现在先敲一敲看看、
图的存储方式有很多,比如邻接矩阵,邻接表,十字链表....感觉还是邻接表比较常见,毕竟看到很多人都在敲-。- (我还是停留在邻接矩阵,难过死了)
定义:一个邻接表是由一个顺序表和一组链表组成的。顺序表中存放图的顶点信息,链表中存放图的边的信息,第 i 个单链表中的节点表示依附于顶点 vi 的边,对于有向图来说,是以顶点 vi 为尾的边。
应用: 在图论当中,几乎都用它,人人都用,不用才怪!
下面看一下实现代码:
#define N 105
struct Edge
{
int to, next, dis;
}edge[3 * N]; // 一般是题意数据的三倍
int head[N];
int k;
void init() // head 数组和 k 的初始化
{
memset(head, -1 , sizeof(head));
k = 1;
}
void addedge(int s, int t, int dist) // 用邻接表实现图的存储,dist 指两点之间的权值,具体看题意而定
{
edge[k].to = t; // to 为边的终点
edge[k].dis = dist;
edge[k].next = head[s];
head[s] = k ++;
}
重点理解:head数组就是指下标,便于遍历,next 就是指向与它有相同顶点的前一个的下标。
像下面的一组数据
起点 终点 head(下标,从1 开始,加入一条边,自身加一)
1 2 1
3 4 2
1 7 3
5 9 4
1 8 5
经过建立邻接表之后
下标1 edge[ 1 ] . to = 2 ; edge[ 1 ] . next = - 1 ; 我们先把它标记为 *
2 edge[ 2 ] . to = 4 ; edge[ 2 ] . next = - 1 ;
3 edge[ 3 ] . to = 7 ; edge[ 3 ] . next = 1 ; 我们先把它标记为#,指向 * 的位置 ,即下标为 1
4 edge[ 4 ] . to = 9 ; edge[ 4 ] . next = - 1 ;
5 edge[ 5 ] . to = 8 ; edge[ 2 ] . next = 3 ; 我们先把它标记为& ,指向 # 的位置,即下标为 3
所以遍历时,从1 开始,它的终点为 2 ,根据next 下一个点为 7, 然后是 8 。
下面是遍历的代码:
for(int i = head[t]; i != -1; i = edge[i].next)
{
......
}
以上就是邻接表了,感觉应该很易懂的吧,我当时看别人的博客看了好久,模拟了好久,还是不会,现在应该理解了一点,但是还是不会用。。。