因为加边后不能有负环且要求边权最小,以6个点u v中的后一个点为起点进行spfa(v)得到的dis[u]取负加入到边集中。
#include <cstdio>
#include <queue>
using namespace std;
const int inf = 0x7fffffff;
const int N = 310;
int a[N][N], dis[N], inq[N], v, e;
void init1(){
for(int i = 0; i < v; ++i){
for(int j = 0; j < v; ++j){
a[i][j] = inf;
}
}
}
void init2(){
for(int i = 0; i < v; ++i){
dis[i] = inf; inq[i] = 0;
}
}
void spfa(int x){
dis[x] = 0;
inq[x] = 1;
queue<int> q;
q.push(x);
while(!q.empty()){
int u = q.front();
q.pop();
inq[u] = 0;
for(int i = 0; i < v; ++i){
if(a[u][i] != inf && dis[i] > dis[u] + a[u][i]){
dis[i] = dis[u] + a[u][i];
if(!inq[i]){
inq[i] = 1;
q.push(i);
}
}
}
}
}
int main()
{
int n;
scanf("%d", &n);
while(n--){
scanf("%d %d", &v, &e);
init1();
for(int i = 0; i < e; ++i){
int u, v, w;
scanf("%d %d %d", &u, &v, &w);
a[u][v] = w;
}
for(int i = 0; i < 6; ++i){
init2();
int u, v;
scanf("%d %d", &u, &v);
spfa(v);
a[u][v] = -dis[u];
printf("%d\n", a[u][v]);
}
}
return 0;
}