P1875 佳佳的魔法药水

思路:
感觉这些题已经不再考你板子了,而是靠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];
}
posted @ 2021-03-07 09:57  yxr~  阅读(61)  评论(0编辑  收藏  举报