题目
https://www.luogu.org/problemnew/show/P1875
思路
类似最短路的思想
将x+y==z看成一条边
每次从图中选择一个已经被更新过的花费最小的点x,
用x去更新能更新的点
直到保留最优解
代码
#include <cstdio>
#include <iostream>
using namespace std;
int cost[9999],ans[9999];
int soc[3000][3000];
bool f[3000];
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&cost[i]),ans[i]=1;
int a,b,c;
while(scanf("%d%d%d",&a,&b,&c)!=EOF)
soc[a+1][b+1]=soc[b+1][a+1]=c+1;
for(int i=1;i<n;i++)
{
int maxn=0x7fffffff;
for(int j=1;j<=n;j++)
if(!f[j]&&cost[j]<maxn)
b=j,maxn=cost[j];
f[b]=1;
for(int j=1;j<=n;j++)
if(f[j]&&soc[b][j])
{
if(cost[b]+cost[j]==cost[soc[b][j]])
ans[soc[b][j]]+=ans[b]*ans[j];
if(cost[b]+cost[j]<cost[soc[b][j]])
cost[soc[b][j]]=cost[b]+cost[j],ans[soc[b][j]]=ans[b]*ans[j];
}
}
printf("%d %d",cost[1],ans[1]);
return 0;
}