Main idea:
You n bottle of liquid medicine, syrup has a weight per p [i], you get a new medicine in two ways
1. Direct later syrup C
2. by synthesizing two syrup such as A + B = C
seeking to give syrup 0 minimum cost and number of options
answer:
The number of solutions for this problem can be thought of similar to the shortest path count, then it needs to be transformed into a graph model.
If dist[i] represents the lowest cost of synthetic potion i, how to update the lowest cost of dist[j].
Traditional shortest path It starts from a point where the shortest path has been determined, u->v uses u to update v. The problem is that two potions synthesize one potion.
Then start from the two points where the shortest path has been determined. If A+B synthesize C
Just use dist[c] >dist[A]+dist[B] to update
. The number of solutions is the template for the shortest path count.
There is a hole when A+A=C, only one edge is needed when saving the picture (the difference between 18 points and 100 points)
Code
int n,head[maxn],cnt,dist[maxn],vis[maxn],link[1600][1600],ans[maxn];
struct node {
int u,v,w,next;
} e[maxn];
void add(int u,int v) {
e[cnt].u=u,e[cnt].v=v;
e[cnt].next=head[u],head[u]=cnt++;
}
void slove() {
priority_queue<PII,vector<PII>,greater<PII> > q;
rep(i,1,n) q.push({
dist[i],i});
while(q.size()) {
PII fr= q.top();
q.pop();
int dian=fr.second;
int dis=fr.first;
if(vis[dian]) continue;
vis[dian]=1;
for(int i= head[dian]; ~i; i=e[i].next) {
int v=e[i].v;
int w = link[dian][v];
if(vis[v]==0) continue;
if(dist[w]>dis+dist[v]) {
dist[w]=dis+dist[v];
ans[w] = ans[v]*ans[dian];
q.push({
dist[w],w});
} else if(dist[w]==dis+dist[v]) {
ans[w]+=ans[v]*ans[dian];
}
}
}
}
int main() {
n=read(),mst(head,-1);
rep(i,1,n) dist[i]=read(),ans[i]=1;
int u,v,w;
while(cin>>u>>v>>w) {
u++,v++,w++;
add(u,v);
if(u==v) continue;
add(v,u);
link[v][u]=w,link[u][v]=w;
}
slove();
printf("%d %d",dist[1],ans[1]);
return 0;
}