bzoj2753
第一问dfs不说
第二问很容易让人想到最小树形图,但是我不会,而且时间复杂度也不允许
还有什么不同的方法呢?
首先想到的是prim的思想,设根节点已经确定,其他点未确定
我们就不断从已确定的点延伸,找到到未确定点中高度最高的那个点的最短边距(如果有多个高度相同的点,肯定选边距最短的)
将边距加入ans,并将这个点标为确定,重复上述,知道所有点都确定即可。
这样的算法没有问题,但是复杂度好像仍然不能AC
我们想,既然我们能用类似prim的思想,为什么不用Kruska呢?
Kruskal的问题在于,这个算法是不涉及到边的方向,用这个不能选出符合条件的解
考虑之前我们用类似prim的思想解题的时候,是以点的高度为第一关键字,然后再以距离为第二关键字
在Kruskal对边排序的时候,我们是不是也可以考虑以点的高度为第一关键字,然后以距离为第二关键字排序呢?
就是这样,我们以边的终点高度为第一关键字降序,长度为第二关键字升序排序
然后按最小生成树的方法做就行了。
结果竟然TLE了,仔细对照一下别人的程序发现一直以来我的并查集写的是有问题的
我原来getfather是这么写的
function getf(x:longint):longint;
begin
while fa[x]<>x do x:=fa[x];
exit(x);
end;
而实际上多次调用这个函数,显然会进行很多冗余的运算
而正确的写法应该是
function getf(x:longint):longint;
begin
if fa[x]<>x then fa[x]:=getf(fa[x]);
exit(fa[x]);
end;
这应该才是并查集所谓反阿克曼函数的时间复杂度吧
亡羊补牢,为时不晚;
type node=record
x,c,y,next:longint;
end; var a:array[..] of node;
fa,p,q,h:array[..] of longint;
v:array[..] of boolean;
len,x,y,z,n,m,i,j,k1,k2,t:longint;
ans,e:int64; procedure swap(var a,b:node);
var c:node;
begin
c:=a;
a:=b;
b:=c;
end; function getf(x:longint):longint;
begin
if fa[x]<>x then fa[x]:=getf(fa[x]); //唉
exit(fa[x]);
end; procedure add(x,y,z:longint);
begin
inc(len);
a[len].y:=y;
a[len].c:=z;
a[len].x:=x;
a[len].next:=p[x];
p[x]:=len;
end; procedure bfs;
var i,f,x,y:longint;
begin
t:=;
q[]:=;
v[]:=true;
f:=;
while f<=t do
begin
x:=q[f];
i:=p[x];
while i<>- do
begin
y:=a[i].y;
if not v[y] then
begin
v[y]:=true;
inc(t);
q[t]:=y;
end;
i:=a[i].next;
end;
inc(f);
end;
end; procedure sort(l,r:longint);
var i,j,x,y,z:longint;
begin
i:=l;
j:=r;
x:=a[(l+r) shr ].c;
y:=a[(l+r) shr ].y;
repeat
while (h[a[i].y]>h[y]) or (h[a[i].y]=h[y]) and (a[i].c<x) do inc(i);
while (h[y]>h[a[j].y]) or (h[a[j].y]=h[y]) and (x<a[j].c) do dec(j);
if not(i>j) then
begin
swap(a[i],a[j]);
inc(i);
j:=j-;
end;
until i>j;
if l<j then sort(l,j);
if i<r then sort(i,r);
end; begin
fillchar(p,sizeof(p),);
readln(n,m);
len:=;
for i:= to n do
read(h[i]);
for i:= to m do
begin
readln(x,y,z);
if h[x]>h[y] then add(x,y,z)
else begin
add(y,x,z);
if h[x]=h[y] then add(x,y,z);
end;
end;
bfs;
sort(,len);
for i:= to n do
fa[i]:=i;
i:=;
j:=;
for j:= to len do
begin
if not(v[a[j].x] and v[a[j].y]) then continue; //首先必须是能访问到的点
k1:=getf(a[j].x);
k2:=getf(a[j].y);
if k1<>k2 then
begin
fa[k2]:=k1;
e:=a[j].c;
ans:=ans+e;
inc(i);
end;
end;
writeln(t,' ',ans);
end.
bzoj2753的更多相关文章
- BZOJ2753 SCOI2012滑雪与时间胶囊(最小生成树)
首先显然可以把所有能到的点拎出来建个新图,这样第一问也就做好了. 剩下的部分似乎是一个裸的最小树形图.但显然这个东西是没什么学的必要的并且不太能跑过去. 考虑建出来的图有什么性质.可以发现如果没有高度 ...
- BZOJ2753 SCOI2012 滑雪与时间胶囊 【最小生成树】*
BZOJ2753 SCOI2012 滑雪与时间胶囊 Description a180285非常喜欢滑雪.他来到一座雪山,这里分布着M条供滑行的轨道和N个轨道之间的交点(同时也是景点),而且每个景点都有 ...
- BZOJ2753 [SCOI2012]滑雪与时间胶囊 【kruskal】
题目链接 BZOJ2753 题解 完了我连\(kruskal\)裸题都做不出来了.. 题目是求最小树形图,即有向图最小生成树 我们不能直接上\(kruskal\),而要保证先加入前面的点, 所以我们排 ...
- Bzoj2753 [SCOI2012]滑雪与时间胶囊
2753: [SCOI2012]滑雪与时间胶囊 Time Limit: 50 Sec Memory Limit: 128 MBSubmit: 2282 Solved: 796 Descriptio ...
- [BZOJ2753][SCOI2012]滑雪与时间胶囊(特殊的有向树形图)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2753 分析: 第一问:直接BFS扩展知道无法扩展 第二问: 看似就是最小树形图啊= = ...
- bzoj2753[SCOI2012]滑雪与时间胶囊 最小生成树
Time Limit: 50 Sec Memory Limit: 128 MBSubmit: 2843 Solved: 993[Submit][Status][Discuss] Descripti ...
- 2019.01.17 bzoj2753: [SCOI2012]滑雪与时间胶囊(最小生成树)
传送门 最小生成树菜题. 题意:给出一些有向边,问有向的最小生成树. 思路:先dfsdfsdfs一把所有有用的边都存起来,然后按终点点权为第一关键字,边权为第二关键字给边排序保证最小生成树的合法性,排 ...
- [BZOJ2753]滑雪与时间胶囊
第一问直接把可以走的边连起来bfs一遍即可 第二问可以用类似kruskal的方法,只不过排序的依据应该变为第一关键字为终点高度(从大到小),第二关键字为边权(从小到大),只排序可以走的边 因为同样高度 ...
- 【bzoj2753】[SCOI2012]滑雪与时间胶囊
#include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> # ...
随机推荐
- js中对闭包的理解
本人丝一枚,在刚刚过去的javascript学习中,对闭包这个知识真是,听课两分钟,懵逼一整天.今天闲来没事,看了下闭包.话不多说先上代码. <!DOCTYPE html> <htm ...
- 百练_4120 硬币(DP)
描述 宇航员Bob有一天来到火星上,他有收集硬币的习惯.于是他将火星上所有面值的硬币都收集起来了,一共有n种,每种只有一个:面值分别为a1,a2… an. Bob在机场看到了一个特别喜欢的礼物,想买来 ...
- [DP] LGTB 玩THD (复杂状态DP)
LGTB 玩THD LGTB 最近在玩一个类似DOTA 的游戏名叫THD有一天他在守一座塔,对面的N 个小兵排成一列从近到远站在塔前面每个小兵有一定的血量hi,杀死后有一定的金钱gi每一秒,他都可以攻 ...
- (int)、(int&)和(int*)的区别(转)
(1).首先通过一个例子看(int)和(int&)的区别: float a = 1.0f;cout << (int)a << endl;cout << (i ...
- Walkthrough: Creating and Using a Dynamic Link Library (C++)
Original Link: http://msdn.microsoft.com/zh-cn/library/ms235636.aspx Following content is only used ...
- ASP.net后台弹出消息对话框的方法!【转】
在winform后台,我们通过MessageBox.show(“消息")的方式来返回后台信息,在webform后台,我们通过Response.write(”消息")来返 ...
- mysql---整体备份和增量备份
整体备份: 对整张表或者整个数据库甚至所有数据库进行备份. 增量备份: 对某一范围内的数据进行备份. 1.整体备份: 对表进行备份: 针对存储引擎为myisam的表,可以直接复制frm.myd.myi ...
- Android开发系列之SQLite
上篇博客提到过SQLite,它是嵌入式数据库,由于其轻巧但功能强大,被广泛的用于嵌入式设备当中.后来在智能手机.平板流行之后,它作为文件型数据库,几乎成为了智能设备单机数据库的必选,可以随着安卓app ...
- 3d旋转--transform-style: preserve-3d,translate3d(x,y,z),perspective()
transform-style: preserve-3d,translate3d(x,y,z),perspective() 让其倾斜的核心:加perspective(600px)让其动的核心:rans ...
- spring data mongodb中,如果对象中的属性不想加入到数据库字段中
spring data mongodb中,如果对象中的属性不想加入到数据库字段中,可加@Transient注解,声明为透明属性 spring data mongodb 官网帮助文档 http://ww ...