P3959 [NOIP2017 提高组] 宝藏(随机化贪心)

题目链接

思路

  • 可以利用random_shuffle()将打通宝藏屋的顺序随机出来,然后贪心求解即可。
  • 即 假如要打通第i个宝藏屋,那么从已打通的宝藏屋中选出打通道路花费最小的即可。

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#define int long long
#define ri register int
#define min(a,b) a<b?a:b
#define inf 0x7f7f7f7f   
using namespace std;
int n,m,ans,an=inf,sum;
int w[15][15];
int a[15],d[15];
int read(){
	int x=0;char c=getchar();
	while(c>'9'||c<'0') c=getchar();
	while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();
	return x;
}
signed main(){
	n=read(),m=read();
	memset(w,127,sizeof w);
	while(m--)
	{
		int u=read(),v=read(),w1=read();
		w[u][v]=w[v][u]=min(w[u][v],w1);
	}	
	for(ri i=1;i<=n;++i) a[i]=i;
	for(ri t=1;t<=100000;++t)//多随机几遍,便于出正确答案 
	{
		random_shuffle(a+1,a+n+1);
		memset(d,0,sizeof d);
		d[a[1]]=1;sum=0;//记得初始化 
		for(ri i=2;i<=n;++i)
		{
			ans=inf;
			for(ri j=1;j<i;++j)
			{
				if(w[a[i]][a[j]]<inf)
				{
					int k=d[a[j]]*w[a[i]][a[j]];
					if(k<ans) ans=k,d[a[i]]=d[a[j]]+1;//求出最小的花费,同时让深度加一 
				}
			}
			if(ans==inf)//如果无法打通,则说明此打通顺序无解,那么就不用再算了 
			{
				sum=inf;
				break;
			}
			else sum+=ans;//打通所需费用累加 
		}
		an=min(an,sum);
	}
	printf("%lld",an);
	return 0;
}

我的状压DP题单

此题另一种解法:状压DP

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Robin_w2321

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值