题目连接
POJ1511
题意
就是说从节点1出发然后问从节点1出发到其它各点的花费与其它各点到节点1之和最小
SPFA可以之结果,但是如果用kuangbin的板子,采用向量(邻接表)的话会超时,应当用链式前向星来作为
数据结构
如果链式前向星不太清楚,可以参考以下博客
链式前向星
代码
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
typedef long long LL;
const int MAXN = 1e6 + 4, INF = 0x3f3f3f3f;
int head1[MAXN], head2[MAXN];
bool found[MAXN];
int dist[MAXN];
struct Edge {
int to, nxt;
int cost;
};
Edge g1[MAXN], g2[MAXN];
LL SPFA(int start, int n, Edge g[], int head[]) {
for (int i = 1; i <= n; ++i) dist[i] = INF;
dist[start] = 0;
queue<int> que;
que.push(start);
while (!que.empty()) {
int u = que.front(); que.pop();
found[u] = false;
for (int i = head[u]; i != -1; i = g[i].nxt) {
int v = g[i].to;
if (dist[v] > dist[u] + g[i].cost) {
dist[v] = dist[u] + g[i].cost;
if (!found[v]) {
found[v] = true;
que.push(v);
}
}
}
}
LL res = 0;
for (int i = 1; i <= n; ++i)
res += dist[i];
return res;
}
void addedge(int u, int v, int w, Edge g[], int& cnt, int head[]) {
++cnt;
g[cnt].to = v; g[cnt].nxt = head[u]; g[cnt].cost = w;
head[u] = cnt;
}
int main() {
int q; scanf("%d", &q);
while (q--) {
int n, m;
scanf("%d%d", &n, &m);
memset(head1, -1, sizeof head1);
memset(head2, -1, sizeof head2);
int cnt1 = 0, cnt2 = 0;
for (int i = 0; i < m; ++i) {
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
addedge(u, v, w, g1, cnt1, head1);
addedge(v, u, w, g2, cnt2, head2);
}
LL res = 0;
res += SPFA(1, n, g1, head1);
res += SPFA(1, n, g2, head2);
printf("%lld\n", res);
}
return 0;
}