# [模板]链式向前星

Invitation Cards 这道题目,8s的时限,1e6的数据,只不过是跑了两边DIjkstra,vector超时,而向前星只需要2s.

### 使用链式向前星存图:

```// N - 节点数, M - 边数
struct E{
int to, wei, nxt;    // nxt即next, 但后者似乎是保留名称
}e[M];
int head[N], ind = 1;
// 下面添加一条由x指向y, 权为w的有向边
inline void add(int x, int y, int w){
e[ind].to = y;
e[ind].wei = w;
e[ind].nxt = head[x];
head[x] = ind++;
}```

### 读取图上信息:

```// 遍历以x为起点的所有边
for(int i = head[cur.to]; i; i = e[i].nxt){
// e[i].to - 当前边指向的终点
// e[i].wei - 当前边的权
// ...operations...
}```

```#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
using namespace std;

struct E{
int to, wei, nxt;
}e[150010];
struct Q{　　// queue_element
int to, wei;
bool operator<(const Q &other)const {return wei > other.wei;}
};
priority_queue<Q> q;
int n, m, head[30010], ind = 1, dist[30010];

inline void add(int x, int y, int w){
e[ind].to = y;
e[ind].wei = w;
e[ind].nxt = head[x];
head[x] = ind++;
}

int main(){
memset(dist, -1, sizeof(dist));
scanf("%d%d", &n, &m);
while(m--){
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
add(a, b, c);
}

q.push({1, 0});
while(!q.empty()){
Q cur = q.top();
q.pop();
if(dist[cur.to] != -1) continue;

dist[cur.to] = cur.wei;
for(int i = head[cur.to]; i; i = e[i].nxt)
if(dist[e[i].to] == -1)
q.push({e[i].to, cur.wei + e[i].wei});
}

printf("%d\n", dist[n] - dist[1]);

return 0;
}```

(后两个是时间(ms)和空间(MB))

```#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;

struct E{   // 这里E和Q可以通用
int to, wei;
bool operator<(const E& other) const {return wei > other.wei;}
};
vector<E> e[30010];
priority_queue<E> q;
int n, m, dist[30010];

inline int read() {
char ch = getchar();
int x = 0, f = 1;
while (ch > ‘9‘ || ch < ‘0‘) {
if (ch == ‘-‘) f = -1;
ch = getchar();
}
while (ch >= ‘0‘ && ch <= ‘9‘) {
x = x * 10 + ch - ‘0‘;
ch = getchar();
}
return x * f;
}

int main(){
memset(dist, -1, sizeof(dist));
n = read(), m = read();
while(m--){
int a, b, c;
a = read(), b = read(), c = read();
e[a].push_back({b, c});
}

q.push({1, 0});
while(!q.empty()){
E cur = q.top();
q.pop();
if(dist[cur.to] != -1) continue;

dist[cur.to] = cur.wei;
for(vector<E>::iterator i = e[cur.to].begin(); i != e[cur.to].end(); i++)
if(dist[i->to] == -1) q.push({i->to, cur.wei + i->wei});
}

printf("%d\n", dist[n] - dist[1]);

return 0;
}```
vector版本,供参考

[模板]链式向前星

(0)
(0)

© 2014 mamicode.com 版权所有