思路:
感觉这些题已经不再考你板子了,而是靠dij的思想
正解就是设置vis表示第i个元素是否已经被制作,把所有药水分成两类,一类被制作,一类还没来得及制作,从还没制作的药水中选择制造价格最小的,判断当前药水是否可以更新已经制作的药水,使得已经制作的药水可以以更小的价格制作,如果两种方式制作价格相同,那么制作方案就是原来的方案加上两种药水制作的方案的乘积,否则,更新当前药水制作最小值,更新方案就是两种新药水的方案的乘积
代码:
#include<bits/stdc++.h>
#define maxnn 3200
using namespace std;
int cost[9999],ans[9999];
int f[3200][3200];
bool vis[9999];
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++) cin>>cost[i],ans[i]=1;
int a,b,c;
while(cin>>a>>b>>c)
{
f[a+1][b+1]=f[b+1][a+1]=c+1;
}
for(int i=1;i<n;i++)
{
int maxn=0x7ffffff;
for(int j=1;j<=n;j++)
if(!vis[j]&&cost[j]<maxn)
{
b=j;
maxn=cost[j];
}//找到未标记的集合中价格最小的药水
vis[b]=1;
for(int j=1;j<=n;j++)
{
if(vis[j]&&f[b][j])
{
if(cost[b]+cost[j]==cost[f[b][j]])//如果这两个药水合成新药水的价值和新药水一样
ans[f[b][j]]+=ans[b]*ans[j];
if(cost[b]+cost[j]<cost[f[b][j]])
cost[f[b][j]]=cost[b]+cost[j],ans[f[b][j]]=ans[b]*ans[j];
}
}
} cout<<cost[1]<<" "<<ans[1];
}