风灵无畏OI

此站用来记录个人的OI成长史,以后会将个人做的每道题的解题报告发到此站上来,希望大家喜欢!(如有讲得不好的地方请大家指出,我会加以改进。当然也有可能传上来一点乱七八糟的东西)
注:转载文章请标上原址,毕竟码字很辛苦!谢谢!

浅谈kruskal另一种应用(二维的kruskal)

【题目描述】

连接格点

问题描述

    有一个M行N列的点阵,相邻两点可以相连。一条纵向的连线花费一个单位,一条横向的连线花费两个单位。某些点之间已经有连线了,试问至少还需要花费多少个单位才能使所有的点全部连通。

输入数据

    第一行输入两个正整数m和n。

    以下若干行每行四个正整数x1,y1,x2,y2,表示第x1行第y1列的点和第x2行第y2列的点已经有连线。输入保证|x1-x2|+|y1-y2|=1。

输出数据

    输出使得连通所有点还需要的最小花费。

输入样例

2 2

1 1 2 1

输出样例

3

时间限制   各测试点1秒

内存限制   你的程序将被分配32MB的运行空间

数据规模 m,n<=1000

【题目大意】

        有一个 M 行 N 列的点阵,相邻两点可以相连。一条纵向的连线花费一个单位,一条横向的连线花 费两个单位。某些点之间已经有连线了,试问至少还需要花费多少个单位才能使所有的点全部连通。

【题目分析】

1.  既然要连通,那么自然想到最小生成树,可是边的数量会很多,而kruskal算法是要用 (ElogE)的时间排序的。肯定超时。

2.  进一步思考,边的权值无非只有3种,已经连好的为0,纵向边为1,横向边为2,那么只要按0,1,2的顺序来存就可以得到有序的边集数组了,然后就是传统的kruskal。

【程序代码】

type  rec=record

         x,y:longint;

       end;

var p:array[1..1000,1..1000]of rec;

      m,n:longint;

function equal(a,b:rec):boolean;

begin

   exit((a.x=b.x) and (a.y=b.y))

end;//判断是否相等,相当于kruskal中判断是否在同一集合中的操作

function findset(x,y:longint):rec;

begin

   if (p[x,y].x<>x) or (p[x,y].y<>y) then

      p[x,y]:=findset(p[x,y].x,p[x,y].y);

   exit(p[x,y]);

end;//相当于kruskal中找爸爸的操作

procedure readp;

var

   x1,y1,x2,y2,i,j:longint;

   t:rec;

begin

   readln(m,n);

   for i:=1 to m do

   for j:=1 to n do

   begin

      t.x:=i;

      t.y:=j;

      p[i,j]:=t;

   end;//初始父亲为自己

   repeat

      readln(x1,y1,x2,y2);

      p[findset(x1,y1).x,findset(x1,y1).y]:=findset(x2,y2);

   until eof;//把本身就已经连了的点放到一个集合中

end;

procedure solve;

var i,j,ans:longint;

begin

   ans:=0;

   for j:=1 to n do

   for i:=1 to m-1 do

      if not equal(findset(i,j),findset(i+1,j)) then

      begin

         p[p[i,j].x,p[i,j].y]:=p[i+1,j];

         inc(ans);

      end;//解决边权为1的边

   for i:=1 to m do

   for j:=1 to n-1 do

      if not equal(findset(i,j),findset(i,j+1)) then

      begin

         p[p[i,j].x,p[i,j].y]:=p[i,j+1];

         inc(ans,2);

      end;//解决边权为2的边

   writeln(ans);

end;

begin

   assign(input,'grid.in');    reset(input);

   assign(output,'grid.out'); rewrite(output);

   readp;

   solve;

   close(input); close(output);

end.


评论

© 风灵无畏OI | Powered by LOFTER