【最小生成树】新的开始(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 ...
随机推荐
- SQLite 入门教程(三)好多约束 Constraints
一.约束 Constraints 在上一篇随笔的结尾,我提到了约束, 但是在那里我把它翻译成了限定符,不太准确,这里先更正一下,应该翻译成约束更贴切一点. 那么什么是约束呢? 我们在数据库中存储数据的 ...
- OSX安装nginx和rtmp模块(rtmp直播服务器搭建)
1.安装Homebrew,执行命令 1 ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/ma ...
- 读懂IL代码(一)
以前刚开始学C#的时候,总有高手跟我说,去了解一下IL代码吧,看懂了你能更加清楚的知道你写出来的代码是如何运行互相调用的,可是那时候没去看,后来补的,其实感觉也不晚.刚开始看IL代码的时候,感觉非常吃 ...
- 不用Google Adsense的84个赚钱方法
这是一个关于网络广告商和网络销售的汇总列表,可以用来为您的网站或博客赚点钱.广告商都是英文的,加入广告请确认其是否支持中国地区支持,不支持的话就不必加入了. Chitika : 购物中心旗帜广告. ( ...
- 掌握JS
1.原生的js,好比全真教的武功,一步步从基础开始(先练气再御剑),很长一段时间内和jquery有很大差距,掌握以后发现jquery只不过是另外一种武功,看一遍既会.且当学原生到一定程度之后,可以自创 ...
- nextDay、beforeDay以及根据nextDay(beforeDay)求解几天后的日期,几天前的日期和两个日期之间的天数
实现代码: package com.corejava.chap02; public class Date { private int year; private int month; private ...
- 【BZOJ2038】【莫队】小z的袜子
Description 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命……具体来说,小Z把这N只袜 ...
- 【POJ2761】【fhq treap】A Simple Problem with Integers
Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. On ...
- php基础知识【函数】(6)mysql数据库
一.连接和关闭 1.mysql_connect('example.com:3307', 'root', '123456') --打开一个到 MySQL 服务器的非永久连接 2.mysql_pconne ...
- [R] /usr/share/doc/apache2/README.Debian.gz
Contents======== Apache2 Configuration under Debian GNU/Linux Files and Directories in '/etc/apache2 ...