题目传送门

  传送点I

  传送点II

题目大意

  给定一个有$n$个点$m$条边的图,每个点有一个高度$h_{i}$,能从$u$经过一条边到达$v$,当且仅当存在一条边是$(u, v)$或$(v, u)$,且$h_{u}\geqslant h_{v}$。问1号点能到达的所有点的最小树形图的边权和。

  第一问沙雕问题。直接一个搜索水过。

  第二问,好像是最小树形图。看着数据范围,嗯,别想朱-刘了。

  感觉可以直接Prim。于是愉快地WA了一发。来回顾一下Prim算法的正确性证明

可以不妨设图中所有边的权重都不同,这样最小生成树是唯一的

设Prim算法得到$G$,而最小生成树是$T$。考虑用反证法。

设在生成G的过程中第一次产生的不在T中的边是$e$,未加入$e$时的点集为$V$。

把$e$加入$T$之后会出现环,这个环内必然存在一条边$f = (u, v) \neq e$使得$u\in V, v\notin V$(因为$e$的一个端点不在$V$中)。由Prim的贪心策略可知$w(e) < w(f)$。用$e$替换掉$f$可以得到更优的生成树,这与最小生成树矛盾。因此$T = G$。

  但树形图不像树那么简单。如果尝试用这种方法去证明可以发现需要讨论两条边的方向,于是很轻松就能卡掉这个zz做法。

  然后如何hack这个zz做法呢?

  于是这个假做法跑出了497的优秀答案。

  好了好了,开始说正题。

  因为不能用朱-刘算法,考虑这样的图有什么样的性质。

  把通过双向边连通的点缩起来。这样剩一个DAG。

  考虑对于一个被缩起来的一块,它自己相当于一个无向图,可以用最小生成树的算法。

  对于连向这个块的出边,它们选还是不选入树形图只对这个块中的选边有影响。

  因此可以将前面的块都看成一个点。然后很有趣的事情来了,直接把这些有向边看成无向边,然后上MST算法。

  为什么这样做是对的。因为我们可以将任意一个树形图映射成一个边权和与它相等的生成树或者一个生成树映射成一个边权和与它相等的树形图。

  做法很简单。前一部分直接将有向边看成无向边,后一部分从 "前面的块都看成一个点" 指的点开始沿着树边bfs,这样就可以定向了。

  具体实现不用将前面的块缩起来。直接以结束点的高度为第一关键字,边权为第二关键字排序即可。

  (虽然我很好奇为什么大家都写Kruskal。显然写Prim可以少写点东西)

Code

 /**
* bzoj
* Problem#
* Accepted
* Time: 13128ms
* Memory: 53364k
*/
#include <bits/stdc++.h>
#ifndef WIN32
#define Auto "%lld"
#else
#define Auto "%I64d"
#endif
using namespace std;
typedef bool boolean; typedef class Edge {
public:
int ed, w; Edge() { }
Edge(int ed, int w):ed(ed), w(w) { }
}Edge; int n, m;
int *hs;
boolean* added;
vector<Edge> *g; boolean operator < (const Edge& a, const Edge& b) {
if (hs[a.ed] ^ hs[b.ed]) return hs[a.ed] < hs[b.ed];
return a.w > b.w;
} inline void init() {
scanf("%d%d", &n, &m);
hs = new int[(n + )];
added = new boolean[(n + )];
g = new vector<Edge>[(n + )];
memset(added, false, sizeof(boolean) * (n + ));
for (int i = ; i <= n; i++)
scanf("%d", hs + i);
for (int i = , u, v, w; i <= m; i++) {
scanf("%d%d%d", &u, &v, &w);
if (hs[u] >= hs[v])
g[u].push_back(Edge(v, w));
if (hs[u] <= hs[v])
g[v].push_back(Edge(u, w));
}
} int rc = ;
long long rv = ;
priority_queue<Edge> que;
inline void solve() {
added[] = true;
for (int i = ; i < (signed) g[].size(); i++)
que.push(g[][i]);
while (!que.empty()) {
while (!que.empty() && added[que.top().ed])
que.pop();
if (que.empty())
break;
Edge e = que.top();
que.pop();
added[e.ed] = true, rc++, rv += e.w;
for (int i = ; i < (signed) g[e.ed].size(); i++)
que.push(g[e.ed][i]);
}
printf("%d "Auto, rc, rv);
} int main() {
init();
solve();
return ;
}

bzoj 2753 [SCOI 2012] 滑雪与时间胶囊 - Prim的更多相关文章

  1. [SCOI 2012]滑雪与时间胶囊

    Description a180285非常喜欢滑雪.他来到一座雪山,这里分布着M条供滑行的轨道和N个轨道之间的交点(同时也是景点),而且每个景点都有一编号i(1<=i<=N)和一高度Hi. ...

  2. BZOJ 2754 SCOI 2012 喵星球上的点名 后缀数组 树状数组

    2754: [SCOI2012]喵星球上的点名 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 2068  Solved: 907[Submit][St ...

  3. 【最小树形图(奇怪的kruskal)】【SCOI 2012】【bzoj 2753】滑雪与时间胶囊

    2753: [SCOI2012]滑雪与时间胶囊 Time Limit: 50 Sec Memory Limit: 128 MB Submit: 1621 Solved: 570 Description ...

  4. 【BZOJ】【2753】【SCOI2012】滑雪与时间胶囊

    Kruskal/最小树形图 然而蒟蒻并不会做这题>_> 本来以为是有向图最小生成树,即最小树形图,但这数据范围有点…… 膜拜了zyf的题解:http://www.cnblogs.com/z ...

  5. BZOJ 2753 [SCOI2012] 滑雪和时间胶囊 最小生成树

    题目链接: 题目 2753: [SCOI2012]滑雪与时间胶囊 Time Limit: 50 Sec Memory Limit: 128 MB 问题描述 a180285非常喜欢滑雪.他来到一座雪山, ...

  6. bzoj 2753: [SCOI2012]滑雪与时间胶囊 -- 最小生成树

    2753: [SCOI2012]滑雪与时间胶囊 Time Limit: 50 Sec  Memory Limit: 128 MB Description a180285非常喜欢滑雪.他来到一座雪山,这 ...

  7. CDOJ 42/BZOJ 2753 滑雪与时间胶囊 kruskal

    2753: [SCOI2012]滑雪与时间胶囊 Time Limit: 50 Sec  Memory Limit: 128 MBSubmit: 1376  Solved: 487[Submit][St ...

  8. 【BZOJ 2753】 2753: [SCOI2012]滑雪与时间胶囊 (分层最小树形图,MST)

    2753: [SCOI2012]滑雪与时间胶囊 Time Limit: 50 Sec  Memory Limit: 128 MBSubmit: 2457  Solved: 859 Descriptio ...

  9. 2753: [SCOI2012]滑雪与时间胶囊

    2753: [SCOI2012]滑雪与时间胶囊 Time Limit: 50 Sec  Memory Limit: 128 MBSubmit: 2633  Solved: 910 Descriptio ...

随机推荐

  1. 比较两种方式的form请求提交

    [一]浏览器form表单提交 表单提交, 适用于浏览器提交.像常见的pc端的网银支付,用户在商户商城购买商品,支付时商家系统把交易数据通过form表单提交到三方支付网关,然后用户在三方网关页面完成支付 ...

  2. html网页什么样的字体最好看,css设置各种中文字体样式代码

    css代码如下:{ font-family:"Microsoft YaHei",微软雅黑,"MicrosoftJhengHei",华文细黑,STHeiti,Mi ...

  3. DataGridView控件用法合集

    1.当前的单元格属性取得.变更 Console.WriteLine(DataGridView1.CurrentCell.Value) Console.WriteLine(DataGridView1.C ...

  4. 【转】LoadRunner压力测试:测试报告结果分析

    见:https://blog.csdn.net/haoui123/article/details/62036723

  5. NSOperation、NSOperationQueue(III)

    NSOperation.NSOperationQueue 常用属性和方法归纳 NSOperation 常用属性和方法 a. 取消操作方法 //可取消操作,实质是标记 isCancelled 状态. - ...

  6. url组成

  7. 2.scrapy安装

    A.Anaconda如果已安装,那么可以通过 conda 命令安装 Scrapy,安装命令如下: conda install Scrapy   ============================ ...

  8. PCB 布线,直角线,差分线,蛇形线

    1.直角线 直角走线的一般标准是PCB布线中要尽量避免的情况,也几乎成为衡量布线好坏的标准之一. 直角走线对信号的影响主要体系那在下面三个方面 1.保教可以等效为传输线是哪个的容性负载,减缓上升时间. ...

  9. Linux服务器---邮件服务openwebmail安装

    安装openwebmail  openwebmail提供了可视化的邮件管理系统,它运行在Apache环境下. 1.安装必备软件 [root@localhost ~]# yum install –y p ...

  10. spring 事物的一些理解

    推荐一个我认为Spring事物写得很好的文章. 文章链接:http://www.codeceo.com/article/spring-transactions.html  文章作者:码农网 – 吴极心 ...