题目大意;有向图,求从1到i的距离和+i到1的距离和(最短)
思路:邻接表建图,正向一个,反向一个。spfa跑两遍即可。。
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <iomanip>
using namespace std;
//#pragma comment(linker, "/STACK:102400000,102400000")
#define maxn 1000005
#define MOD 1000000007
#define mem(a , b) memset(a , b , sizeof(a))
#define LL long long
#define INF 100000000
int p , q;
struct edge
{
int u , v , w;
int next;
}E[maxn],E2[maxn];
int head[maxn] , head2[maxn];
int cost[maxn];
int id , id2;
void add(int u , int v , int w)
{
E[id].u = u;
E[id].v = v;
E[id].w = w;
E[id].next = head[u];
head[u] = id++;
}
void add2(int u , int v , int w)
{
E2[id2].u = u;
E2[id2].v = v;
E2[id2].w = w;
E2[id2].next = head2[u];
head2[u] = id2++;
}
void spfa(int root , edge E[] , int head[])
{
for(int i = 2 ; i <= p ; i ++) cost[i] = INF;
cost[1] = 0;
queue<int>Q;
Q.push(root);
while(!Q.empty())
{
int u = Q.front();
Q.pop();
for(int i = head[u] ; i >= 0 ; i = E[i].next)
{
if(cost[E[i].v] > cost[u] + E[i].w)
{
cost[E[i].v] = cost[u] + E[i].w;
Q.push(E[i].v);
}
}
}
}
int main()
{
int t;
scanf("%d" , &t);
while(t--)
{
scanf("%d %d" , &p , &q) ;
id = 0;id2 = 0;
mem(head , -1);mem(head2 , -1);
int u , v , w;
for(int i = 1 ; i <= q ; i ++)
{
scanf("%d %d %d" , &u , &v , &w);
add(u , v , w);
add2(v , u , w);
}
LL ans = 0;
spfa(1 , E , head);
for(int i = 1 ; i <= p ; i ++) ans += cost[i];
spfa(1 , E2 , head2);
for(int i = 1 ; i <= p ; i ++) ans += cost[i];
printf("%lld\n" , ans);
}
return 0;
}