关于链式前向星

虽然很多人肯定都会了,我还是加深一下印象吧

首先,链式前向星需要一个结构体:

struct Edge //存边
{
    int v, w, nxt;
}edge[m];

v,w分别是终点,边权

若这条边的起点为u,则nxt是u的上一条出边的编号

还需要一个数组:

int head[n];

head[u]表示目前u的最后一条出边

还需要一个变量

int cnt;

表示边的数量

那加边就可以写出来了

void add(int u, int v, int w)
{
    ++cnt;
    edge[cnt].v = v; //终点
    edge[cnt].w = w; //边权
    edge[cnt].nxt = head[u]; //见下
    head[u] = cnt;
}

函数的后两行对我来说比较难理解

下面说的"边"指的是u的出边

最新的边(新加的边)的上一条边就是之前的最后一条边

最新的边是edge[cnt],最新的边的上一条边是edge[cnt].nxt

之前的最后一条边是head[u],所以edge[cnt].nxt = head[u]

那最后一行就是更新目前最后一条边(即新加的边)的编号

遍历一个点的出边也很简单了:

for(int i = head[u]/*最后一条出边*/;i/*还有出边*/;i = edge[i].nxt/*切换到上一条出边*/)

附赠dijk:

#include <iostream>
#include <queue>
#include <utility>
#include <functional>
using namespace std;
struct Edge
{
    int v, w, nxt;
}edge[200001];
int head[100001], cnt, n, m, s, u, v, w, dis[100001], vis[100001];
priority_queue<pair<int, int>, vector<pair<int, int> >, greater<pair<int, int> > > q;
void add(int u, int v, int w)
{
    ++cnt;
    edge[cnt].v = v;
    edge[cnt].w = w;
    edge[cnt].nxt = head[u];
    head[u] = cnt;
}
int main()
{
    cin >> n >> m >> s;
    for(int i = 0;i < m;++i)
        cin >> u >> v >> w, add(u, v, w);
    for(int i = 1;i <= n;++i)
        dis[i] = 2147483647;
    dis[s] = 0;
    q.push(make_pair(0, s));
    while(!q.empty())
    {
        int u = q.top().second;q.pop();
        if(vis[u]) continue;
        vis[u] = 1;
        for(int i = head[u];i;i = edge[i].nxt)
            if(dis[edge[i].v] > dis[u] + edge[i].w)
                dis[edge[i].v] = dis[u] + edge[i].w, q.push(make_pair(dis[edge[i].v], edge[i].v));
    }
    for(int i = 1;i <= n;++i)
        cout << dis[i] << " ";
    return 0;
}
posted @ 2021-07-16 09:54  5k_sync_closer  阅读(4)  评论(0编辑  收藏  举报  来源