解题报告 跑步

 

1.        题目

跑步(Running.pas/c/cpp

题目描述

      新兵到部队,警官要求他们每天早上搞晨跑,从A营跑到B营。从A营到B营中有n-2个路口,分别标上号,A营为1号,B营为n号,路口分别为2..n-1号,从A营到B营有很多条路径可以到达,而睿智的警官发现有的路口是必须经过的,即每条路径都经过的路口,警官要把它们记录下来,这样警官就可以先到那个路口,观察新兵有没有偷懒,而你的任务就是找出所有必经路口。

输入数据

   第一行两个用空格隔开的整数n(3<=n<=2000)和e(1<=n<=8000)。

   接下来从第2到第e+1行,每行两个用空格隔开的整数p和q,表示路口p和q之间有路径直达。

   输入数据保证必经路口一定存在,并且每个路口都和A营、B营相连通。

输出数据

    第一行一个整数m,表示必经路口的数目。

第二行按从小到大的顺序依次输出每个必经路口的编号,每两个数之间用一个空格隔开。

注意:不包括起点和终点。

 

样例输入

6 6

1 2

2 4

2 3

3 5

4 5

5 6

 

样例输出

2

2 5

 

2.        题目实质

给出一个无向图,要求求出其中的关键点(从起点到终点必经过的点)。

3.        算法

注意,不要傻傻的去求割点。这个算法不好写,更重要的是,它根本不对。

这可是第一题,用不着类似于割点、桥这样的知识点。

 

其实,他的正解是枚举+图的遍历。

首先,枚举每一个点,再把这一个点去掉,遍历整个图,如果能走到 n ,则说明这个点不是关键点,反之,则记录。

然后,就是这样。

4.        注意事项

审题,不要求割点!

5.        程序代码

SueMiller Pascal

var n,e:integer;

    a:array[0..2010,0..2010]of integer;

    ans:array[0..2010]of integer;

    v:array[0..2010]of boolean;

    x,y,i,j,k:integer;

 

procedure dfs(x:integer);

var i:integer;

begin

  v[x]:=true;

  for i:=1 to a[x,0] do

    if not v[a[x,i]] then dfs(a[x,i]);

  exit;

end;

 

begin

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

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

 

  readln(n,e);

  fillchar(a,sizeof(a),false);

  for i:=1 to e do

    begin

      read(x,y);

      inc(a[x,0]);

      a[x,a[x,0]]:=y;

      inc(a[y,0]);

      a[y,a[y,0]]:=x;

    end;

  fillchar(ans,sizeof(ans),0);

 

  for k:=2 to n-1 do

    begin

      fillchar(v,sizeof(v),false);

      v[k]:=true;

      dfs(1);

      if not v[n] then begin

        inc(ans[0]);

        ans[ans[0]]:=k;end;

    end;

 

  writeln(ans[0]);

  for i:=1 to ans[0] do write(ans[i],' ');

  close(input);close(output);

end.

6.        囧囧的惊残孤梦

话说,在三个月以前,本人还不会遍历一张图……甚至连邻接表都打着很费劲……不用指针根本写不出来……经典算法是按文科的学习方法------背!

时过境迁、沧海桑田啊,这个代码, 5 分钟……

原文地址:https://www.cnblogs.com/SueMiller/p/2130757.html