zoukankan      html  css  js  c++  java
  • 链式前向星

    声明


       题目

        给你一个有 n 个点和 m 条边(允许有重边)的无向图及每条边的边权,求:和点 k 所有相连的边的终点和边权,以及相连的边数。(此题也可暴力枚举,但为了讲前向星,还是用了前向星来做)

      输入输出格式:

        输入格式:

          输入数据第一行两个数 n,m,意义如题目所示。

          接下来 m 行每行有 3 个用空格隔开的数,其中第 i 行的 3 个数 x[i],y[i],w[i] 分别表示第 i 条边的起点、终点和边权。

          最后一行仅一个数 k,表示要查询的点,查询内容如题所示。

        输出格式:

          共 t+1 行。

          前 t 行每行两个数,其中第 j 行的两个数分别代表第 j 条与 k 相连的边的终点和边权,之间用空格隔开。

          最后一行一个整数 s,表示与 k 点相连的边数。

          注意:输出的前 t 行的边的顺序可以打乱,即第 j 条边放在某一条边的前面或后面输出是同样的答案,但禁止重复输出(除非两条相同的边)!!!

      样例输入:  

        4  5
        1  4  3
        3  2  2
        1  2  1
        4  3  4
        1  4  2
        4  

      

      样例输出

        1  2
        3  4
        1  3
        3

      介绍:前向星用一维数组实现,是邻接矩阵(二维数组实现)的优化,大大节省了存储空间和查找时间,在图论和需建图解题的题目中发挥着极大的作用!!!(当然此题也可以用邻接矩阵做,但数据一旦超过 3000 ,甚至达到 一万  或 十万  甚至 百万千万  的话,邻接矩阵就完全无能为力了)

      了解之后,让我们来真正接触一下前向星吧!


      

          First:构建链式前向星~(也是核心步骤

                  
     1 procedure add(x,y,z:longint);      //加一条从 x 到 y 的边权为 w 的边
     2 begin
     3        inc(tot);                              //此条边的编号
     4        next[tot]:=first[x];              // next 记录下一条边的编号(边的顺序 
     5                                                    无所谓)
     6        first[x]:=tot;                       // first 记录第一条边的编号(哪条边作 
     7                                                    为第一条边也无所谓)
     8        en[tot]:=y;                         // en 记录编号为 tot 的边的终点
     9        len[tot]:=z;                        // len 记录编号为 tot 的边的边权
    10 end;
    建链表函数
             
    1 for i:=1 to m do              
    2 begin
    3         readln(x,y,w);  
    4         add(x,y,w);          //调用函数建表(正向建一次) 
    5         add(y,x,w);          //调用函数建表(反向建一次)
    6 end;    
    7 (因为是无向边,所以要正反建两次~)
    主程序调用建表函数以完成建前向星过程

           Next:线性查询!!!      

                
    now:=first[k];                           //找起点为 k 的第一条边的编号
    
    while now<>0 do                      //当边的编号不为零即还有边未询问是进 
                                                      行线性查询
    begin
    
        writeln(en[now],' ',len[now]);//找到一条边,就输出信息,因为可以乱 
                                                     序(若按字典序输出,则存进数组里排 
                                                     一下序就好啦~)
    
        now:=next[now];                //线性查询下一条边(查询操作中的精 
                                                    髓!)
    
        inc(cnt);                            //累计边的个数
    
    end;
    查询过程

          Last:输出~

              其实你们应该早发现了,在线性查询的过程中以经输出过终点和边权了,且剩下要输出的边数 s 其实就是 t 即程序中的 cnt !!!(废话!这只要是个人都能看出来的好吗?!)
          于是 writeln(cnt); 就完美地结束了此题!!!

          

         以下是标程!!!

                 
     1 var
     2         x,y,w,tot,i,n,k,now,e,m,cnt:longint;
     3         first,en,next,len:array[0..1000001] of longint;
     4 procedure add(x,y,w:longint);    //建表函数
     5 begin
     6         inc(tot);
     7         next[tot]:=first[x];
     8         first[x]:=tot;
     9         en[tot]:=y;
    10         len[tot]:=w;
    11 end;
    12 begin
    13         readln(n,m);
    14         for i:=1 to m do               //调用函数建表
    15         begin
    16                 readln(x,y,w);
    17                 add(x,y,w);
    18                 add(y,x,w);
    19         end;
    20         readln(k);
    21         now:=first[k];                //开始查询
    22         while now<>0 do
    23         begin
    24                 writeln(en[now],' ',len[now]); //边询问边输出
    25                 now:=next[now];
    26                 inc(cnt);
    27         end;
    28         writeln(cnt);                   //最后输出边数此题完美结束
    29 end.
    标程

        

           学后推荐一个用到前向星的模板:最小生成树 Prim 算法

  • 相关阅读:
    请求参数的中文乱码问题
    MySql索引与优化
    Android 兼容包
    Mysql 主从(转)
    解决tomcat一闪而过(转)
    log4j
    支付相关
    通过maven添加quartz
    linux命令学习之:chmod
    Nginx特点及其配置
  • 原文地址:https://www.cnblogs.com/t-s-y/p/10311873.html
Copyright © 2011-2022 走看看