【最小生成树】新的开始(newstart) 解题报告
【题目描述】
发展采矿业当然首先得有矿井, 小FF花了上次探险获得的千分之一的财富请人在岛上挖了n口矿井, 但他似乎忘记考虑的矿井供电问题…… 为了保证电力的供应, 小FF想到了两种办法:
- 在这一口矿井上建立一个发电站,费用为v(发电站的输出功率可以供给任意多个矿井)。
- 将这口矿井与另外的已经有电力供应的矿井之间建立电网, 费用为p。小FF希望身为”NewBe_One" 计划首席工程师的你帮他想出一个保证所有矿井电力供应的最小花费。
【输入格式】
第一行一个整数n, 表示矿井总数。 第2~n+1行,每行一个整数, 第i个数v[i]表示在第i口矿井上建立发电站的费用。 接下来为一个n*n的矩阵P, 其中p[ i , j ]表示在第i口矿井和第j口矿井之间建立电网的费用(数据保证有p[ i, j ] = p[ j, i ], 且 p[ i, i ]=0)。
【输出格式】仅一个整数, 表示让所有矿井获得充足电能的最小花费。
【输入样例】
4
5
4
4
3
0 2 2 2
2 0 3 3
2 3 0 4
2 3 4 0
【输出样例】
9
输出样例说明: 小FF可以选择在4号矿井建立发电站然后把所有矿井都与其建立电网,总花费是 3+2+2+2 =9。
【数据范围】
对于30%的数据: 1<=n<=50;
对于100%的数据: 1<=n<=300; 0<=v[i], p[i,j] <=10^5.
分析:
第一眼看上去是一个MST(最小生成树),唯一不同的是题中有一个发电站的概念,如果将它与MST的问题分隔开,先求MST再来选择价值最小的发电站的话(即贪心思路),是不能保证求出最优解的,因为这样就默认了每个矿井都必须是连通的,当边权特别大,不取这条边,分别修两个电站才是最优的。因此贪心的方案是错的,没有把题中两个关键的元素联系起来。正确的解法是在原图的基础上虚拟一个点,原图的每一个节点都与这个虚拟点有一条边,边权为在该点上修建电站的花费。从而得到一个新图,对新图的求MST,结果结果就是MST的边权和。这是一种模型转换的思路,十分值得借鉴。
贪心的思路没有将题目整体考虑,所以要得到正确的解题模型,整体考虑题目往往非常重要。
贪心思路是我在考试时想的错误方法,编程复杂不说还WA了。
下面修改过后用模型转换思路得到的AC代码:
/*
ID: ringxu97
LANG: C++
TASK: Newstart
SOLUTION: 生成树
*/
#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
using namespace std;
const int maxn=300+10;
const int inf=0x3f3f3f3f;
int n;
struct DisjointSet//并查集
{
int n;
int fa[maxn];
DisjointSet(const int &k):n(k)
{
for(int i=1;i<=k;++i)
fa[i]=i;
}
int Get(int a)
{
if(fa[a]==a)return a;
else return fa[a]=Get(fa[a]);
}
void Union(int a,int b)
{
fa[Get(a)]=Get(b);
}
bool Same(int a,int b)
{
return Get(a)==Get(b);
}
};
struct EDGE
{
int u,v,w;
}E[maxn*maxn/2];//边表
inline bool cmp(EDGE a,EDGE b)
{
return a.w<b.w;
}
EDGE *p=E;
void addedge(int u,int v,int w)//向边表中加边
{
p->u=u;
p->v=v;
(p++)->w=w;
}
int price[maxn];
int G[maxn][maxn];
int ans=0;
void read()//读入数据
{
scanf("%d",&n);
for(int i=1;i<=n;++i)
{
scanf("%d",price+i);
}
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
{
int tmp;
scanf("%d",&tmp);
if(j>i)
{
addedge(i,j,tmp);//无向边
}
}
for(int i=1;i<=n;++i)
{
addedge(i,n+1,price[i]);//虚拟点为n+1,与原图各点连边
}
} void Kruskal()//求MST
{
memset(G,0,sizeof(G));
DisjointSet ds(n+1);
sort(E,p,cmp);
for(EDGE *i=E;i<p;++i)
{
if(!ds.Same(i->u,i->v))
{
ans+=i->w;
ds.Union(i->u,i->v);
}
}
}
int main()
{
read();
Kruskal();
printf("%d\n",ans);
return 0;
}
【最小生成树】新的开始(newstart) 解题报告的更多相关文章
- LeetCode 新题: Find Minimum in Rotated Sorted Array 解题报告-二分法模板解法
Find Minimum in Rotated Sorted Array Question Solution Suppose a sorted array is rotated at some piv ...
- $HNOI\ 2010$ 解题报告
HNOI 2010 解题报告 0. HNOI2010 AC代码包下载地址 注: 戳上面的标题中的'地址' 下载 代码包, 戳下面每一题的文件名 可进入 题目链接. 每一题 对应代码的文件名 我在 每一 ...
- 北大ACM试题分类+部分解题报告链接
转载请注明出处:優YoU http://blog.csdn.net/lyy289065406/article/details/6642573 部分解题报告添加新内容,除了原有的"大致题意&q ...
- 冲刺Noip2017模拟赛2 解题报告——五十岚芒果酱
题1 牛跑步(running) [题目描述] 新牛到部队,CG 要求它们每天早上搞晨跑,从 A 农场跑到 B 农场.从 A 农场到 B 农场中有 n- 个路口,分别标上号,A 农场为 号,B 农场为 ...
- 习题:codevs 2822 爱在心中 解题报告
这次的解题报告是有关tarjan算法的一道思维量比较大的题目(真的是原创文章,希望管理员不要再把文章移出首页). 这道题蒟蒻以前做过,但是今天由于要复习tarjan算法,于是就看到codevs分类强联 ...
- 习题:codevs 1519 过路费 解题报告
今天拿了这道题目练练手,感觉自己代码能力又增强了不少: 我的思路跟别人可能不一样. 首先我们很容易就能看出,我们需要的边就是最小生成树算法kruskal算法求出来的边,其余的边都可以删掉,于是就有了这 ...
- Mutual Training for Wannafly Union #1解题报告
---恢复内容开始--- q神等人组织的vjudge上的多校训练,题目基本上都来自于CF,#1是上周进行的,参加后感觉收获很多,因为上周准备期中比较忙,解题报告现在补上. 比赛地址(兼题目地址) A题 ...
- Codeforces Round #378 (Div. 2) D题(data structure)解题报告
题目地址 先简单的总结一下这次CF,前两道题非常的水,可是第一题又是因为自己想的不够周到而被Hack了一次(或许也应该感谢这个hack我的人,使我没有最后在赛后测试中WA).做到C题时看到题目情况非常 ...
- 【NOIP2015】提高day2解题报告
题目: P1981跳石头 描述 一年一度的“跳石头”比赛又要开始了!这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石.组委会已经选择好了两块岩石作为比赛起点和终点.在起点和终点之间,有 N ...
随机推荐
- sql查看数据库表使用情况
如有更好的方式,希望交流. 感谢热心人,cc谢过 EXEC sys.sp_MSforeachtable @precommand = N'create table ##( 表名 sys ...
- asp.net mvc4 使用java异步提交form表单时出现[object object] has no method ajaxSubmit
最近接手了一个单子,说大不大,只是功能不少,开发过程中遇到该问题 先看脚本截图: 本以为是笔误,哪儿写错了,可是看来看去,都没发现有不合适的地方,对比过网上很多代码,都差不多,于是各种方式的,各种原因 ...
- bash: ./configure: 权限不够 怎么办?
configure没有执行权限 通过chmod给其加上x权限 chmod +x configure 再在该用户下执行 ./configure
- 用户组,AD域控简介
“自由”的工作组 工作组(WORK GROUP)就是将不同的电脑按功能分别列入不同的组中,以方便管理.比如在一个网络内,可能有成百上千台工作电脑,如果这些电脑不进行分组,都列在“网上邻居”内,可 ...
- linux常用编辑器
管理员在进行系统操作的时候,不可避免地会对文本进行修改,如进行各种服务程序配置文件的改动,使程序对用户提供不同的服务效果.在本章我们向大家介绍Linux上常见的编辑器ed.vi.emacs,同时以vi ...
- 用java写bp神经网络(四)
接上篇. 在(一)和(二)中,程序的体系是Net,Propagation,Trainer,Learner,DataProvider.这篇重构这个体系. Net 首先是Net,在上篇重新定义了激活函数和 ...
- 用java写bp神经网络(二)
接上篇. Net和Propagation具备后,我们就可以训练了.训练师要做的事情就是,怎么把一大批样本分成小批训练,然后把小批的结果合并成完整的结果(批量/增量):什么时候调用学习师根据训练的结果进 ...
- 纯命令行教你Cocoapods的安装和使用
关于cocoapods的介绍和作用,网上有很多大神介绍的比我清楚,建议去看一下唐巧的http://blog.devtang.com/blog/2014/05/25/use-cocoapod-to-ma ...
- Spring 中的注解
1.普通方式注解 a.在配置文件中配置 1.导入命名空间 xmlns:context="http://www.springframework.org/schema/ ...
- ios开发之IBOutlet和IBAction的区别
IBOutlet 输出口是使用关键字IBOutlet声明的实例变量.控制器头文件中的输出口声明应如下所示: @property (nonatomic, retain) IBOutlet UIButto ...