首页 > 其他分享 >[洛谷P3959][NOIP2017提高组] 宝藏

[洛谷P3959][NOIP2017提高组] 宝藏

时间:2023-02-12 13:12:55浏览次数:48  
标签:NOIP2017 小明 le 洛谷 样例 times P3959 道路 宝藏

[NOIP2017 提高组] 宝藏

题目描述

参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 \(n\) 个深埋在地下的宝藏屋, 也给出了这 \(n\) 个宝藏屋之间可供开发的 \(m\) 条道路和它们的长度。

小明决心亲自前往挖掘所有宝藏屋中的宝藏。但是,每个宝藏屋距离地面都很远,也就是说,从地面打通一条到某个宝藏屋的道路是很困难的,而开发宝藏屋之间的道路则相对容易很多。

小明的决心感动了考古挖掘的赞助商,赞助商决定免费赞助他打通一条从地面到某个宝藏屋的通道,通往哪个宝藏屋则由小明来决定。

在此基础上,小明还需要考虑如何开凿宝藏屋之间的道路。已经开凿出的道路可以 任意通行不消耗代价。每开凿出一条新道路,小明就会与考古队一起挖掘出由该条道路所能到达的宝藏屋的宝藏。另外,小明不想开发无用道路,即两个已经被挖掘过的宝藏屋之间的道路无需再开发。

新开发一条道路的代价是 \(\mathrm{L} \times \mathrm{K}\)。其中 \(L\) 代表这条道路的长度,\(K\) 代表从赞助商帮你打通的宝藏屋到这条道路起点的宝藏屋所经过的宝藏屋的数量(包括赞助商帮你打通的宝藏屋和这条道路起点的宝藏屋) 。

请你编写程序为小明选定由赞助商打通的宝藏屋和之后开凿的道路,使得工程总代价最小,并输出这个最小值。

输入格式

第一行两个用空格分离的正整数 \(n,m\),代表宝藏屋的个数和道路数。

接下来 \(m\) 行,每行三个用空格分离的正整数,分别是由一条道路连接的两个宝藏屋的编号(编号为 \(1-n\)),和这条道路的长度 \(v\)。

输出格式

一个正整数,表示最小的总代价。

样例 #1

样例输入 #1

4 5 
1 2 1 
1 3 3 
1 4 1 
2 3 4 
3 4 1

样例输出 #1

4

样例 #2

样例输入 #2

4 5 
1 2 1 
1 3 3 
1 4 1 
2 3 4 
3 4 2

样例输出 #2

5

提示

【样例解释 \(1\)】

小明选定让赞助商打通了 \(1\) 号宝藏屋。小明开发了道路 \(1 \to 2\),挖掘了 \(2\) 号宝藏。开发了道路 \(1 \to 4\),挖掘了 \(4\) 号宝藏。还开发了道路 \(4 \to 3\),挖掘了 \(3\) 号宝藏。

工程总代价为 $1 \times 1 + 1 \times 1 + 1 \times 2 = 4 $。

【样例解释 \(2\)】

小明选定让赞助商打通了 \(1\) 号宝藏屋。小明开发了道路 \(1 \to 2\),挖掘了 \(2\) 号宝藏。开发了道路 \(1 \to 3\),挖掘了 \(3\) 号宝藏。还开发了道路 \(1 \to 4\),挖掘了 \(4\) 号宝藏。

工程总代价为 \(1 \times 1 + 3 \times 1 + 1 \times 1 = 5\)。

【数据规模与约定】

对于 $ 20%$ 的数据: 保证输入是一棵树,\(1 \le n \le 8\),\(v \le 5\times 10^3\) 且所有的 \(v\) 都相等。

对于 \(40\%\) 的数据: \(1 \le n \le 8\),\(0 \le m \le 10^3\),\(v \le 5\times 10^3\) 且所有的 \(v\) 都相等。

对于 $ 70%$ 的数据: \(1 \le n \le 8\),\(0 \le m \le 10^3\),\(v \le 5\times 10^3\)。

对于 $ 100%$ 的数据: \(1 \le n \le 12\),\(0 \le m \le 10^3\),\(v \le 5\times 10^5\)。

这个数据范围,一看就知道是状压 dp。同时肯定是一层一层dp的。

定义 \(dp_{i,s1,s2}\) 为现在层数为 \(i\),已经开通了的点是 \(s1\),最后一层是 \(s2\),然后要枚举 \(s3\) 为下一层所连的点集合,转移。

但是这样复杂度会爆炸。发现其实 \(s2\) 不用记在 dp 范围内。因为当 \(s3\) 接到不是最近一层的点时,他的代价会更劣,本来没有 \(i\) 层被算成了 \(i\) 层。所以我们只要找出 \(s1\) 和 \(s3\) 的所有连接方式中最优的就行了。

\(s3\) 子集枚举,复杂度 \(O(n3^n)\)

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=13;
int n,m,g[N][N];
LL ans=1e18,dp[1<<N][N];//dp[s][i]:
int main()
{
	memset(dp,0x7f,sizeof(dp));
	memset(g,0x7f,sizeof(g));
	scanf("%d%d",&n,&m);
	for(int i=1,u,v,w;i<=m;i++)
	{
		scanf("%d%d%d",&u,&v,&w),--u,--v;
		g[u][v]=g[v][u]=min(g[u][v],w);
	}
	for(int i=0;i<n;i++)
		dp[1<<i][1]=0;
	for(int i=1;i<(1<<n);i++)
	{
		for(int j=i&(i-1);j;j=(j-1)&i)
		{
//			printf("%d %d\n",i,j);
			int s=i^j,ret=0,fl=0;
			for(int a=0;a<n;a++)
			{
				if(j>>a&1)
				{
					int mn=1e6;
					for(int b=0;b<n;b++)
						if(s>>b&1&&g[a][b])
							mn=min(mn,g[a][b]);
					if(mn==1e6)
						fl=1,a=n;
					ret+=mn;
				}
			}
			if(fl)
				continue;
			for(int k=2;k<=n;k++)
				dp[i][k]=min(dp[i][k],dp[s][k-1]+ret*1LL*(k-1));
		}
	}
//	for(int i=1;i<(1<<n);i++)
//	{
//		for(int j=1;j<=n;j++)
//			printf("%d ",dp[i][j]);
//		puts("");
//	}
	for(int i=1;i<=n;i++)
		ans=min(ans,dp[(1<<n)-1][i]);
	printf("%lld",ans);
}

标签:NOIP2017,小明,le,洛谷,样例,times,P3959,道路,宝藏
From: https://www.cnblogs.com/mekoszc/p/17113678.html

相关文章

  • [洛谷P5368] 真实排名
    [PKUSC2018]真实排名题目描述小C是某知名比赛的组织者,该比赛一共有\(n\)名选手参加,每个选手的成绩是一个非负整数,定义一个选手的排名是:成绩不小于他的选手的数量(包括......
  • 洛谷 P1223 排队接水
    原题链接题解C++存在一种pair类型,并且可以指定first/second的数据类型,所以可以使用它来代替只有两个元素的结构体利用sort对数据进行排序,将取水时间从小到大排序为什......
  • 洛谷 P2240 部分背包问题
    原题链接题解这道题是贪心只要按照性价比最高的取一定得到的价值最大性价比就是这堆金币的价值除以重量只需要把这些金币按性价比排序就行了最后在超出和未超出之间......
  • 洛谷 P2014 选课 树形依赖背包
    题目描述在大学里每个学生,为了达到一定的学分,必须从很多课程里选择一些课程来学习,在课程里有些课程必须在某些课程之前学习,如高等数学总是在其它课程之前学习。现在有N门功......
  • 树形DP依赖背包 洛谷 P2015 二叉苹果树
    题目描述有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点)这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1。我们用一根树枝两端连接的......
  • 种类并查集 洛谷 P2024 食物链
    题目描述动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形。A吃B,B吃C,C吃A。现有N个动物,以1-N编号。每个动物都是A,B,C中的一种,但是我们并不知道......
  • POJ 3276 Face The Right Way/洛谷P2882 [USACO07MAR]面对正确的方式 反转
    题目描述FarmerJohnhasarrangedhisN(1≤N≤5,000)cowsinarowandmanyofthemarefacingforward,likegoodcows.Someofthemarefacingbackward,th......
  • 洛谷 P2412 查单词
    这是一个非常有意思的题……这一个题放在线段树里面显得非常清奇。很多题解并没有用线段树,或者是用的线段树方法很难。因此,这里为初学者献上一份较为简单容易看懂的代码。......
  • 洛谷oj题单【入门2】分支结构-入门难度(Java)
    洛谷oj题单【入门2】分支结构-入门难度(Java)来源:https://www.luogu.com.cn/training/101#problemsP5709【深基2.习6】ApplesPrologue/苹果和虫子importjava.util.Sc......
  • 洛谷P9035 Pont des souvenirs 题解
    题面很简洁,这里不做多说。70pts做法首先考虑到\(a_{n-1}\)和\(a_n\)两项是整个数列\(a\)中的最大的两项,所以若\(a_{n-1}+a_n\)不超过\(k+1\),则数列中任意两项......