题目链接:P1629 邮递员送信
程序说明:
注意每次只能拿一件物品,送到目的地后必须返回起点才能送下一件。
因此可以将题目转化为:从1号点到其余各点的最短路,再加上其余各点到1号点的最短路即为正确答案。
求多个点到1号点的最短路,可以将邻接矩阵坐标互换(即将有向图反转)。
代码如下:
#include <iostream>
#include <cstring>
using namespace std;
const int N = 1010, M = 100010;
int g[N][N], dist[N], st[N], n, m, res;
void dijkstra() {
memset(dist, 0x3f, sizeof dist);
memset(st, 0, sizeof st); //注意要将st数组清零
dist[1] = 0;
for(int i = 0; i < n; i++) {
int t = -1;
for(int j = 1; j <= n; j++)
if(!st[j] && (t == -1 || dist[j] < dist[t]))
t = j;
st[t] = 1;
for(int j = 1; j <= n; j++)
dist[j] = min(dist[j], dist[t] + g[t][j]);
}
}
int main() {
memset(g, 0x3f, sizeof g);
cin>>n>>m;
while(m--) {
int x, y, z;
cin>>x>>y>>z;
g[x][y] = min(g[x][y], z);
}
dijkstra();
for(int i = 1; i <= n; i++)
res += dist[i];
//将图反转
for(int i = 1; i <= n; i++)
for(int j = i + 1; j <= n; j++)
swap(g[i][j], g[j][i]);
dijkstra();
for(int i = 1; i <= n; i++)
res += dist[i];
cout<<res;
return 0;
}