主要思路:Dijkstra + DP
如果做过最短路计数,这道题就相当于双倍经验了。
就是在跑Dijkstra时,另计一个 (t_i) 作为到第 (i) 个点时最短路的条数,一个 (rs_i) 作为到第 (i) 个点最短路点权和的最大值
注意一下维护条数时要分类,是不是 (dis) 更新了,更新了要用新值覆盖掉之前的数值。
还有,点的编号 (0) ~ (n-1),边是双向边,千万别搞错了
部分代码:
struct wtf{
int t,r,rs;
}r[505];
struct node{
int u,d;
friend bool operator<(const node &a,const node &b){
return a.d>b.d;
}
};
void Dijkstra(){
for(int i=0;i<=n-1;i++) dis[i]=inf;
dis[c1]=0, r[c1].t = 1;
priority_queue<node>q;
node x;
x.u=c1,x.d=0;
q.push(x);
while(!q.empty()) {
node fr = q.top();
q.pop();
int u = fr.u, d = fr.d;
if(d != dis[u]) continue;
for(int i = head[u]; i != -1; i = e[i].next) {
int v = e[i].to, w = e[i].w;
if(dis[u] + w <= dis[v]) {
bool flag = 0;
if(dis[u] + w < dis[v])
r[v].t = r[u].t,
flag = 1;
else if(dis[u] + w == dis[v])
r[v].t = r[v].t + r[u].t;
r[v].rs = max(r[u].rs + r[v].r, r[v].rs);
dis[v] = dis[u] + w;
if(flag) {
node y;
y.u = v, y.d = dis[v];
q.push(y);
}
}
}
}
}
P.S. :帮人改代码时看到的题,高三里第一次敲代码,,,高三继续加(tui)油(fei)!