USACO 2014 JAN滑雪场评级{Gold题3}

滑雪场评级{Gold3}

【问题描述】

   滑雪场用一个M*N(1 <= M,N <= 500)的数字矩阵表示海拔高度,每个数字表示一个范围在0 .. 1,000,000,000的高度。有些格子被指定为起点,组织者想对这些起点做难度评级。

如果起点P点是一个难度级别为D的起点,则D必须是满足以下条件的一个最小值:

(1)从一个格子只能滑到相邻的格子;

(2)这两个格子的海拔差不超过D;

(3)至少能够到达T(1 <= T <= M*N)个格子(包括起点本身)。

【文件输入】

第一行,三个用空格隔开的整数,分别表示M,N和T。

接下来2.. M+1行,每行一个N个整数,表示海拔。

接下来M+2.. 2M+1行,每行一个整数0或者1,其中1表示该格子是一个起点。

【文件输出】

    共一行,一个整数,所有起点的难度和。

【输入样例】

3 5 10

20 21 18 99 5

19 22 20 16 17

18 17 40 60 80

1 0 0 0 0

0 0 0 0 0

0 0 0 0 1

【输出样例】

24

【样例说明】

左上角的格子是一起点,难度为4,右下角的格子是一个起点,难度为20。 

思路:这道题原来以为只要二分再搜索就可以AC了,结果发现差的还是有点远了,只过了一个点。后来请教某大牛得知原来这题的算法主要是用最小生成树的kruskal算法,把整个图用边连接起来,边的权值等于两个点之间的高度差绝对值,然后对边进行快排,每次加入最小的一条边,当边数大于题目要求的t时,深搜整个图,此时搜到的起点的难度值即为当前加进去边的权值。下面上代码

  1 type node=record
  2  s,t,w:longint;
  3 end;
  4 
  5 var
  6 v:array[0..500000]of node;                   //v表示每条边的端点以及权值
  7 fa,size:array[0..250000]of longint;          //fa表示每个点的父节点;size表示每个连通块所包含的点的数量
  8 h:array[0..500,0..500]of longint;
  9 used,isstart:array[0..250000]of boolean;     //used表示每个点是否已经搜索过;isstart表示该点是否为起点
 10 map:array[0..250000,0..4]of longint;         //map表示每个点所连通的点
 11 n,m,kk,ss,ans:int64;                         //ss表示边的条数
 12 
 13 procedure openit;
 14  begin
 15   assign(input,'skilevel.in');assign(output,'skilevel.out');
 16   reset(input);rewrite(output);
 17  end;
 18 
 19 procedure closeit;
 20  begin
 21   close(input);close(output);
 22  end;
 23 
 24 procedure qsort(l,r:longint);
 25  var i,j,m:longint;
 26      t:node;
 27   begin
 28    i:=l;j:=r;m:=v[(l+r) div 2].w;
 29    repeat
 30     while v[i].w<m do inc(i);
 31     while v[j].w>m do dec(j);
 32     if not (i>j) then
 33      begin
 34       t:=v[i];v[i]:=v[j];v[j]:=t;
 35       inc(i);dec(j);
 36      end;
 37    until i>j;
 38    if l<j then qsort(l,j);
 39    if i<r then qsort(i,r);
 40   end;
 41 
 42 function getfather(x:longint):longint;
 43  begin
 44   if fa[x]=x then exit(x);
 45   fa[x]:=getfather(fa[x]);
 46   getfather:=fa[x];
 47  end;
 48 
 49 procedure datain;
 50  var i,j,num:longint;
 51   begin
 52    readln(n,m,kk);
 53    for i:=1 to n do
 54     begin
 55      for j:=1 to m do read(h[i,j]);
 56      readln;
 57     end;
 58    for i:=1 to n do
 59     begin
 60      for j:=1 to m do
 61       begin
 62        read(num);
 63        if num=1 then isstart[(i-1)*m+j]:=true;
 64       end;
 65      readln;
 66     end;
 67    for i:=1 to n do
 68     for j:=1 to m do
 69      begin
 70       if i<n then
 71        begin
 72         inc(ss);
 73         v[ss].s:=(i-1)*m+j;
 74         v[ss].t:=i*m+j;
 75         v[ss].w:=abs(h[i,j]-h[i+1,j]);
 76        end;
 77       if j<m then
 78        begin
 79         inc(ss);
 80         v[ss].s:=(i-1)*m+j;
 81         v[ss].t:=(i-1)*m+j+1;
 82         v[ss].w:=abs(h[i,j]-h[i,j+1]);
 83        end;
 84      end;
 85    for i:=1 to n*m do            //初始化
 86     begin
 87      fa[i]:=i;
 88      size[i]:=1;
 89     end;
 90    qsort(1,ss);                  //快排权值
 91   end;
 92 
 93 procedure dfs(pos,cur:longint);
 94  var i:longint;
 95   begin
 96    used[pos]:=true;
 97    if isstart[pos] then
 98     begin
 99      ans:=ans+cur;
100      isstart[pos]:=false;
101     end;
102    for i:=1 to map[pos,0] do
103     if not used[map[pos,i]] then dfs(map[pos,i],cur);
104   end;
105 
106 procedure kruskal;                    //运用最小生成树的思想进行求解
107  var i,j,x,y:longint;
108   begin
109    for i:=1 to ss do
110     begin
111      x:=getfather(v[i].s);
112      y:=getfather(v[i].t);
113      if x<>y then
114       begin
115        if (size[x]<kk) and (size[x]+size[y]>=kk) then dfs(x,v[i].w);
116        if (size[y]<kk) and (size[x]+size[y]>=kk) then dfs(y,v[i].w);
117        fa[y]:=x;
118        size[x]:=size[x]+size[y];
119        inc(map[v[i].s,0]);
120        map[v[i].s,map[v[i].s,0]]:=v[i].t;
121        inc(map[v[i].t,0]);
122        map[v[i].t,map[v[i].t,0]]:=v[i].s;
123       end;
124     end;
125   end;
126 
127 
128 begin
129  openit;
130  datain;
131  kruskal;
132  writeln(ans);
133  closeit;
134 end.
原文地址:https://www.cnblogs.com/p0226/p/4074662.html