首先,是直接采用邻接矩阵的方式来正向建图,算1到各个结点的最短距离,ans累加。
然后,算2到各个结点的最短距离,res累加各结点到1的距离。
然后,超时。毕竟 O ( n 3 ) O(n^3) O(n3)
再之后,看了各大佬题解后(洛谷)
看到了反向建图的思路
,于是有了,如下AC代码
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <cmath>
using namespace std;
const int N = 3e3 + 10;
int g[N][N];
int g1[N][N];
int n,m;
bool st[N],st1[N];
int dis[N];
int dis1[N];
int dijkstra(){
memset(dis,0x3f,sizeof(dis));
dis[1] = 0;
for(int i = 1; i <= n; i++){
int t = -1;
for(int j = 1; j<=n; j++){
if(!st[j] && (t == -1 || dis[t] > dis[j]))
t = j;
}
st[t] = true;
for(int j = 1; j <= n; j++){
dis[j] = min(dis[j],dis[t] + g[t][j]);
}
}
int ans = 0;
for(int i = 2; i <= n; i++){
ans += dis[i];
}
//下面代码会TLE,只能过4个点
// int res = 0;
// for(int i = 2; i <= n; i++){
// memset(dis,0x3f,sizeof(dis));
// memset(st,0,sizeof(st));
// dis[i] = 0;
// for(int j = 1; j <= n; j++){
// int t = -1;
// for(int k = 1; k <= n; k++){
// if(!st[k] && (t == -1 || dis[t] > dis[k]))
// t = k;
// }
// st[t] = true;
// for(int k = 1; k <= n; k++){
// dis[k] = min(dis[k], dis[t] + g[t][k]);
// }
// }
// res += dis[1];
// }
return ans;
}
int dijkstra1(){
memset(dis1,0x3f,sizeof(dis1));
dis1[1] = 0;
for(int i = 1; i <= n; i++){
int t = -1;
for(int j = 1; j <= n; j++){
if(!st1[j] && (t == -1 || dis1[t] > dis1[j]))
t = j;
}
st1[t] = true;
for(int j = 1; j <= n; j++){
dis1[j] = min(dis1[j], dis1[t] + g1[t][j]);
}
}
int res = 0;
for(int i = 1; i <= n; i++){
res += dis1[i];
}
return res;
}
int main(){
scanf("%d%d",&n,&m);
memset(g,0x3f,sizeof(g));
memset(g1,0x3f,sizeof(g1));
while(m--){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
g[a][b] = min(g[a][b],c);
g1[b][a] = min(g1[b][a],c);
}
int t = dijkstra();
int t1 = dijkstra1();
// cout << t <<" " << t1 << endl;
printf("%d\n",t + t1);
return 0;
}