分析:求最短路径的条数,以及最短路径中点权和最大的那条路径的点权之和。Dijkstra+DFS即可
官网测试点中坑点:
1、最短路径条数不等于目标节点的入度
2、存在起点和终点相同的情况,若代码写的挫,需要特判。。
代码:
#include <cstdio>
#include <vector>
#include <cstring>
using namespace std;
const int maxv = 500+5;
const int INF = 1<<28;
int G[maxv][maxv];
bool vis[maxv];
int d[maxv];
int weight[maxv];
vector<int> pre[maxv];
int n, m;
int st, ed;
int ans, num;
void Dij(int s) {
memset(vis, 0, sizeof(vis));
fill(d, d+maxv, INF);
for(int i = 0; i < n; ++i)
pre[i].push_back(i);
d[s] = 0;
for(int i = 0; i < n; ++i) {
int u = -1, MIN = INF;
for(int j = 0; j < n; ++j) {
if(vis[j] == false && d[j] < MIN) {
u = j;
MIN = d[j];
}
}
if(u == -1) return;
vis[u] = true;
for(int v = 0; v < n; ++v) {
if(vis[v] == false && G[u][v] != INF) {
if(d[u]+G[u][v] < d[v]) {
d[v] = d[u]+G[u][v];
pre[v].clear();
pre[v].push_back(u);
}
else if(d[u]+G[u][v] == d[v]) {
pre[v].push_back(u);
}
}
}
}
}
void DFS(int v, int sum) {
if(v == st) {
ans = max(ans, sum);
num++;
return;
}
for(int i = 0; i < pre[v].size(); ++i) {
int u = pre[v][i];
DFS(u, sum+weight[u]);
}
}
int main() {
scanf("%d %d %d %d", &n, &m, &st, &ed);
for(int i = 0; i < n; ++i)
scanf("%d", &weight[i]);
fill(G[0], G[0]+maxv*maxv, INF);
for(int i = 0; i < m ; ++i) {
int u, v, val;
scanf("%d %d %d", &u, &v, &val);
G[u][v] = val;
G[v][u] = val;
}
Dij(st);
ans = 0, num = 0;
for(int i = 0; i < pre[ed].size(); ++i) {
int u = pre[ed][i];
DFS(u, weight[ed]+weight[u]);
}
if(st == ed) ans = weight[ed];
printf("%d %d\n", num, ans);
return 0;
}
下面是不用特判的。先找出最优路径再求点权和。
#include <cstdio>
#include <vector>
#include <cstring>
using namespace std;
const int maxv = 500+5;
const int INF = 1<<28;
int G[maxv][maxv];
bool vis[maxv];
int d[maxv];
int weight[maxv];
vector<int> pre[maxv];
vector<int> path, temp_path;
int optval;
int n, m;
int st, ed;
int ans, num;
void Dij(int s) {
memset(vis, 0, sizeof(vis));
fill(d, d+maxv, INF);
for(int i = 0; i < n; ++i)
pre[i].push_back(i);
d[s] = 0;
for(int i = 0; i < n; ++i) {
int u = -1, MIN = INF;
for(int j = 0; j < n; ++j) {
if(vis[j] == false && d[j] < MIN) {
u = j;
MIN = d[j];
}
}
if(u == -1) return;
vis[u] = true;
for(int v = 0; v < n; ++v) {
if(vis[v] == false && G[u][v] != INF) {
if(d[u]+G[u][v] < d[v]) {
d[v] = d[u]+G[u][v];
pre[v].clear();
pre[v].push_back(u);
}
else if(d[u]+G[u][v] == d[v]) {
pre[v].push_back(u);
}
}
}
}
}
void DFS(int v) {
if(v == st) {
temp_path.push_back(v);
int value = 0;
for(int i = temp_path.size()-1; i >= 0; --i) {
int id = temp_path[i];
value += weight[id];
}
if(value > optval) {
optval = value;
path = temp_path;
}
num++;
temp_path.pop_back();
return;
}
temp_path.push_back(v);
for(int i = 0; i < pre[v].size(); ++i) {
DFS(pre[v][i]);
}
temp_path.pop_back();
}
int main() {
scanf("%d %d %d %d", &n, &m, &st, &ed);
for(int i = 0; i < n; ++i)
scanf("%d", &weight[i]);
fill(G[0], G[0]+maxv*maxv, INF);
for(int i = 0; i < m ; ++i) {
int u, v, val;
scanf("%d %d %d", &u, &v, &val);
G[u][v] = val;
G[v][u] = val;
}
Dij(st);
ans = 0, num = 0;
DFS(ed);
for(int i = 0; i < path.size(); ++i)
ans += weight[path[i]];
printf("%d %d\n", num, ans);
return 0;
}