一、题目链接
二、题目分析
(一)算法标签
最短路
(二)解题思路
三、AC代码
解法一:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int N = 1010, M = 1e5 + 10, INF = 1e9;
int g[N][N];
int n, m;
int a, b, c;
bool st[N];
int dist[N];
// 反向建边(矩阵转置即可)
void transpose()
{
for (int i = 1; i <= n; i ++ )
for (int j = i + 1; j <= n; j ++ )
swap(g[i][j], g[j][i]);
}
void spfa()
{
memset(dist, 0x3f, sizeof dist);
dist[1] = 0;
queue<int> q;
q.push(1);
st[1] = true;
while (!q.empty())
{
auto t = q.front();
q.pop();
st[t] = false;
// 找t可以直接到的点
for (int i = 1; i <= n; i ++ )
{
if (i == t) continue; // 是t就continue
if (g[t][i] == INF) continue; // t -> i 不存在边就continue
if (dist[i] > dist[t] + g[t][i])
{
dist[i] = dist[t] + g[t][i];
if (!st[i])
{
q.push(i);
st[i] = true;
}
}
}
}
}
int main()
{
cin >> n >> m;
for (int i = 1; i <= n; i ++ )
for (int j = 1; j <= n; j ++ )
if (i == j) g[i][j] = 0;
else g[i][j] = INF;
for (int i = 0; i < m; i ++ )
{
scanf("%d%d%d", &a, &b, &c);
g[a][b] = min(c, g[a][b]);
}
int ans = 0;
spfa();
for (int i = 2; i <= n; i ++ ) ans += dist[i];
transpose();
spfa();
for (int i = 2; i <= n; i ++ ) ans += dist[i];
cout << ans << endl;
return 0;
}
Floyd:(TLE 40分)
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1010, M = 1e5 + 10, INF = 1e9;
int h[N], w[M], e[M], ne[M], idx;
void add(int a, int b, int c)
{
e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx ++ ;
}
int n, m;
int a, b, c;
int d[N][N];
int main()
{
cin >> n >> m;
for (int i = 1; i <= n; i ++ )
for (int j = 1; j <= n; j ++ )
if (i == j) d[i][j] = 0;
else d[i][j] = INF;
for (int i = 0; i < m; i ++ )
{
scanf("%d%d%d", &a, &b, &c);
d[a][b] = min(c, d[a][b]);
// d[a][b] = c;
}
for (int k = 1; k <= n; k ++ )
for (int i = 1; i <= n; i ++ )
for (int j = 1; j <= n; j ++ )
d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
int ans = 0;
for (int i = 2; i <= n; i ++ ) ans += d[1][i] + d[i][1];
cout << ans << endl;
return 0;
}