题意:n个点,m条有向边,求从点1到各点再从各点回到点1的最小路程和
从点1到个点——单源最短路
从各点回到点1——由于是单向边,所以去和回所经过的路程可能不一样且都回到1——反向建图,重新转化成1到各点——单源最短路
#include<stdio.h>
#include<string.h>
struct rec {
int x;
int y;
int len;
};
struct rec ll[100010];
int l = 0;
int last[1010], dis[1010];
int pre[100010], other[100010], len[100010];
int que[1010];
int vis[1010];
void connect(int x, int y, int z) {
pre[++l] = last[x];
last[x] = l;
other[l] = y;
len[l] = z;
}
void spfa(void) {
int h = 0;
int tl = 1;
int p, q, cur;
memset(vis, 0, sizeof(vis));
memset(dis, 127, sizeof(dis));
que[1] = 1; dis[1] = 0; vis[1] = 1;
while (h != tl) {
h = (h % 1000) + 1;
cur = que[h];
vis[cur] = 0;
q = last[cur];
while (q != 0) {
p = other[q];
if (dis[p] > dis[cur] + len[q]) {
dis[p] = dis[cur] + len[q];
if (vis[p] == 0) {
vis[p] = 1;
tl =(tl % 1000) +1;
que[tl] = p;
}
}
q = pre[q];
}
}
}
int main(){
int ans = 0;
int n, m, x, y, z;
int i;
scanf("%d %d", &n, &m);
for (i = 1; i <= m; i++) {
scanf("%d %d %d", &x, &y, &z);
connect(x, y, z);
ll[i].x = x;
ll[i].y = y;
ll[i].len = z;
}
//
spfa();
//
for (i = 2; i <= n; i++) ans += dis[i];
//for (i = 2; i <= n; i++) printf("%d %d\n", i, dis[i]);
//
l = 0;
memset(last, 0, sizeof(last));
for (i = 1; i <= m; i++) connect(ll[i].y, ll[i].x, ll[i].len);
spfa();
//
for (i = 2; i <= n; i++) ans += dis[i];
//
printf("%d\n", ans);
}
——Eirlys