洛谷 P1875 佳佳的魔法藥水
阿新 • • 發佈:2020-10-25
題目傳送門
類似Dijkstra的思想,每次找到花費最少的那個點i,然後找到所有能和i組合且已經已經被更新成花費最小的點更新其他點.
方案數的話,運用乘法原理.
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int n,a[1101],y,x,z,g[1001][1001],ans[1001]; bool vis[1001]; inline void dij() { for(int i = 1;i < n; i++) { int mx = 999999999,id; for(int j = 0;j < n; j++) if(!vis[j] && a[j] < mx) id = j,mx = a[j]; vis[id] = 1; for(int j = 0;j < n; j++) if(g[id][j] != -1 && vis[j]) { if(a[id] + a[j] < a[g[id][j]]) { ans[g[id][j]] = ans[id] * ans[j]; a[g[id][j]] = a[id] + a[j]; continue; } if(a[id] + a[j] == a[g[id][j]]) ans[g[id][j]] += ans[id] * ans[j]; } } } int main() { scanf("%d",&n); memset(g,-1,sizeof(g)); for(int i = 1;i <= n; i++) { scanf("%d",&a[i-1]); ans[i-1] = 1; } while(scanf("%d%d%d",&x,&y,&z) != EOF) { g[x][y] = z; g[y][x] = z; } dij(); printf("%d %d",a[0],ans[0]); return 0; }