双向的spfa遍历的时候
(别忘了初始化 多组输入)
对于存放的边转化的问题 可以有多种实现方式
链式前向星的存储
我们可以开两个边集的数组来实现(一次就可以完成)
也可以通过一个 数组的储存来实现(两次循环的加边)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#include <cmath>
using namespace std;
#define inf 0x3f3f3f3f
typedef long long ll;
const int MAXN = 1e6+7;
int n,m,t,cnt,s = 1;
ll ans;
ll dis[MAXN];
int vis[MAXN];
int head[MAXN];
int a[MAXN][3];// 用这样一个数组 来存放 输入的边的信息 这样可以 通过重新加边 来实现 第二次的 spfa的遍历
struct node
{
int to,next,w;
}edge[MAXN];
void addedge(int u,int v,int w)
{
edge[++cnt].to = v;
edge[cnt].w = w;
edge[cnt].next = head[u];
head[u] = cnt;
}
void init()
{
memset(head,0,sizeof(head));
memset(vis,0,sizeof(vis));
memset(dis,inf,sizeof(dis));
cnt = 0;
dis[s] = 0;
}
void spfa()
{
queue<int>q;
q.push(s);
vis[s] = 1;
while(!q.empty())
{
int top = q.front();
q.pop();
vis[top] = 0;
for(int i = head[top];i != 0;i = edge[i].next)
{
if(dis[edge[i].to] > dis[top] + edge[i].w)
{
dis[edge[i].to] = dis[top] + edge[i].w;
if(!vis[edge[i].to])
{
vis[edge[i].to] = 1;
q.push(edge[i].to);
}
}
}
}
for(int i = 1;i <= n;i ++)
ans += dis[i];
}
int main()
{
cin>>t;
while(t--)
{
scanf("%d%d",&n,&m);
//int s,e,cost;
ans = 0;
init();
for(int i = 1;i <= m;i ++)
{
scanf("%d%d%d",&a[i][0],&a[i][1],&a[i][2]);
addedge(a[i][0],a[i][1],a[i][2]);
}
spfa();
init();
for(int i = 1;i <= m;i ++)
addedge(a[i][1],a[i][0],a[i][2]);
spfa();
printf("%lld\n",ans);
}
return 0;
}