直接分析输入输出。
点数n、边数m、起点st、终点ed
点权
边权
最短路算法无非dijkstra、Floyd、SPFA,这里以dijkstra算法为例。
在dijkstra的基础上再引入三个数组:weg[],点权,w[]记录最大点权,way[]记录最短路条数。
下面分析dij()函数:
//邻接矩阵G[][],最短路数组dis[],访问数组vis[]
void dij(int st, int ed)//传入起点、终点
{
//初始化(从0开始计数)
for (int i = 0; i < n; ++i) {
vis[i] = 0;
w[i] = 0;
dis[i] = G[st][i];
}
w[st] = weg[st];//起点的点权
way[st] = 1;//起点到起点的路径为1
dis[st] = 0;
for (int i = 0; i < n; ++i) {
int x = -1, mx = inf;
for (int j = 0; j < n; ++j) {
if (!vis[j] && dis[j] < mx) {
x = j;
m = dis[j];
}
}
if (x == -1) return;//若x为-1,则该点与其他点都不联通。
for (int j = 0; j < n; ++j)
if (!vis[j] && G[x][j] != inf) {
if (dis[j] == dis[x] + G[x][j]) { //走中转站和不走中转站都一样
//那就比点权
if (w[j] < w[x] + weg[j]) w[j] = w[x] + weg[j];
way[j] += way[x]; //再加上一条从中转站过来的路
} else if (dis[j] > dis[x] + G[x][j]) {//可松弛
dis[j] = dis[x] + G[x][j];
way[j] = way[x]; //要走最短路必须走中转站,故直接覆盖。
w[j] = w[x] + weg[j];
}
}
}
printf("%d %d", way[ed], w[ed]);
}
一下为我的AC代码,与题解的命名不一致,有需者请悉知。
#include <iostream>
using namespace std;
const int inf = 1e7+7;
const int maxn = 505;
//w为邻接矩阵,n为点数,m为边数,dis为最短路
int w[maxn][maxn], n, m, dis[maxn];
//team为点权,tms记录最大点权和,way记录最短路径条数
int team[maxn], tms[maxn], way[maxn];
bool v[maxn];
void dij(int st, int end)
{
for (int i = 0; i < n; ++i) {
dis[i] = w[st][i];
v[i] = 0;
way[i] = 0;
}
dis[st] = 0;
tms[st] = team[st];
way[st] = 1;
for (int i = 0; i < n; ++i) {
int x = -1, mx = inf;
for (int j = 0; j < n; ++j)
if (!v[j] && dis[j] < mx) {
x = j;
mx = dis[j];
}
if (x == -1) return;
v[x] = 1;
for (int j = 0; j < n; ++j)
if (!v[j] && w[x][j] != inf) {
if (dis[j] == dis[x] + w[x][j]) {
if (tms[x] + team[j] > tms[j]) tms[j] = tms[x] + team[j];
way[j] += way[x];
} else if (dis[j] > dis[x] + w[x][j]) {
dis[j] = dis[x] + w[x][j];
way[j] = way[x];
tms[j] = tms[x] + team[j];
}
}
}
printf("%d %d", way[end], tms[end]);
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cin >> n >> m;
for (int i = 0; i < n; ++i)
for (int j = 0; j < n; ++j)
w[i][j] = inf;
int a, b ,c, st, end;
cin >> st >> end;
for (int i = 0; i < n; ++i) cin >> team[i];
for (int i = 0; i < m; ++i) {
cin >> a >> b >> c;
w[a][b] = c;
w[b][a] = c;
}
dij(st, end);
return 0;
}
原文:https://www.cnblogs.com/xdaniel/p/12631155.html