第一问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的更多相关文章

  1. BZOJ2753 SCOI2012滑雪与时间胶囊(最小生成树)

    首先显然可以把所有能到的点拎出来建个新图,这样第一问也就做好了. 剩下的部分似乎是一个裸的最小树形图.但显然这个东西是没什么学的必要的并且不太能跑过去. 考虑建出来的图有什么性质.可以发现如果没有高度 ...

  2. BZOJ2753 SCOI2012 滑雪与时间胶囊 【最小生成树】*

    BZOJ2753 SCOI2012 滑雪与时间胶囊 Description a180285非常喜欢滑雪.他来到一座雪山,这里分布着M条供滑行的轨道和N个轨道之间的交点(同时也是景点),而且每个景点都有 ...

  3. BZOJ2753 [SCOI2012]滑雪与时间胶囊 【kruskal】

    题目链接 BZOJ2753 题解 完了我连\(kruskal\)裸题都做不出来了.. 题目是求最小树形图,即有向图最小生成树 我们不能直接上\(kruskal\),而要保证先加入前面的点, 所以我们排 ...

  4. Bzoj2753 [SCOI2012]滑雪与时间胶囊

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

  5. [BZOJ2753][SCOI2012]滑雪与时间胶囊(特殊的有向树形图)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2753 分析: 第一问:直接BFS扩展知道无法扩展 第二问: 看似就是最小树形图啊= = ...

  6. bzoj2753[SCOI2012]滑雪与时间胶囊 最小生成树

    Time Limit: 50 Sec  Memory Limit: 128 MBSubmit: 2843  Solved: 993[Submit][Status][Discuss] Descripti ...

  7. 2019.01.17 bzoj2753: [SCOI2012]滑雪与时间胶囊(最小生成树)

    传送门 最小生成树菜题. 题意:给出一些有向边,问有向的最小生成树. 思路:先dfsdfsdfs一把所有有用的边都存起来,然后按终点点权为第一关键字,边权为第二关键字给边排序保证最小生成树的合法性,排 ...

  8. [BZOJ2753]滑雪与时间胶囊

    第一问直接把可以走的边连起来bfs一遍即可 第二问可以用类似kruskal的方法,只不过排序的依据应该变为第一关键字为终点高度(从大到小),第二关键字为边权(从小到大),只排序可以走的边 因为同样高度 ...

  9. 【bzoj2753】[SCOI2012]滑雪与时间胶囊

    #include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> # ...

随机推荐

  1. 2.2_线性表的顺序存储结构_参考集合ArrayList

    [线性表的顺序存储从结构] 指的是用一段连续的存储单元一次储存线性表的数据元素. [线性表的顺序存储的结构代码 C语言版] #define MAXSIZE 20 /*存储空间初始分配量*/ typed ...

  2. QT/C++ 智能指针

    什么是智能指针? 为什么用智能指针? 还有哪些关于内存管理方面的知识点,需要注意的?

  3. sql的集合操作

    原文转自:http://blog.csdn.net/qsyzb/article/details/12560917 SELECT语句的查询结果是元组的集合,所以多个SELECT语句的结果可进行集合操作. ...

  4. 重新安装Ubuntu12.04

    重新安装Ubuntu12.04 之所以我重新安装Ubuntu,因为我第一次给根目录分配的空间过小,好像是20GB吧~结果编译Android的时候,编译了3个小时候直接中止掉了.郁闷.这个也告诉我们一定 ...

  5. 《APUE》第三章笔记(4)及习题3-2

    APUE第三章的最后面给出的函数,现在还用不着,所以,先留个名字,待到时候用着了再补上好了. dup和dup2函数:用来复制文件描述符的 sync函数,fsync函数和fdatasync函数:大致的功 ...

  6. 今日吐槽20151208.net服务器控件

    正文 今天有个小任务是给页面添加一个搜索条件,复选框多选.因为页面都是服务器控件,我也只能用服务器控件配合了.然后给页面加了一个  CheckBoxList  控件.后台通过数据表加载数据. fore ...

  7. 如何使用 require.js ,实现js文件的异步加载,避免网页失去响应,管理模块之间的依赖性,便于代码的编写和维护。

    一.为什么要用require.js? 最早的时候,所有Javascript代码都写在一个文件里面,只要加载这一个文件就够了.后来,代码越来越多,一个文件不够了,必须分成多个文件,依次加载.下面的网页代 ...

  8. Python SqlAlchemy使用方法

    1.初始化连接 from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker engine = create ...

  9. Educational Codeforces Round 8 D. Magic Numbers

    Magic Numbers 题意:给定长度不超过2000的a,b;问有多少个x(a<=x<=b)使得x的偶数位为d,奇数位不为d;且要是m的倍数,结果mod 1e9+7; 直接数位DP;前 ...

  10. IIS Handler and Module探索

    Create Handler & Module Run the Visual Studio Create a Class Library “HMHandler” --> Change t ...