切换到宽版
  • 13321阅读
  • 11回复

哈利·波特与魔法石 [复制链接]

上一主题 下一主题
离线gelanjie
 
只看楼主 倒序阅读 0 发表于: 2005-11-07
题目描述

  在Super Samuel星球上,有n个城市,每两个城市都可以直接或间接到达,城市之间的路存在着不同的地形,通过每种地形所需时间是不同的,而且时间是固定的,但是路的长短却并不重要。如果路上有魔法石的话,则通过该路的时间将会减半。(如果城市1与城市2之间有路,我们认为城市1可以直接到城市2,城市2也可以直接到城市1)。现在求从a城市和 b城市最少需要花费多少时间。

算法分析

  这是一道典型求最短路径的题目。
  由于题目上说每两个城市之间的路最多只有一条,那么我们就可以用Road[i,j]来存放从城市i到城市j所需的时间。Road[i,j]如果为0,则代表从城市i不能直接到城市j 。而对于路a----b来说,我们可以知道通过路所在地形所花去的时间,如果这种地形有魔法石,则将时间减半。在所有城市之间的地图构造好之后,我们就可以利用Dijstra算法求出从城市a到城市b所需的最短时间了。
  至此,本题已经得到圆满的解决

程序如下:

Const
  InFile = 'AH02T7.in';
  OutFile = 'AH02T7.out';
  Limit = 102;
  MaxLongint = 10000000;
  cost : array[1..7] of longint
     = (2 , 6 , 4 , 8 , 6 , 10 , 14);

Type
  Tmap = array[1..Limit , 1..Limit] of longint;
  Tappeared = array[1..Limit] of boolean;
  Tshortest = array[1..Limit] of longint;

Var
  map : Tmap;
  appeared : Tappeared;
  shortest : Tshortest;
  start ,
  stop : longint;

procedure init;                   // 初始化
type
  Tdata = array[1..7] of longint;
var
  data : Tdata;
  i ,
  p1 , p2 ,
  k , total : longint;
begin
  fillchar(appeared , sizeof(appeared) , 0);
  for p1 := 1 to Limit do
   for p2 := 1 to Limit do
    map[p1 , p2] := maxlongint;
  assign(INPUT , InFile); ReSet(INPUT);
   for i := 1 to 7 do
    begin
      read(data);
      inc(data);
    end;
   read(start , stop , total);
   for i := 1 to total do
    begin
       read(p1 , p2 , k);
       map[p1 , p2] := cost[k] div data[k];
       map[p2 , p1] := cost[k] div data[k];
       appeared[p1] := true;
       appeared[p2] := true;
    end;
  Close(INPUT);
end;

procedure work; {Dijkstra}           // 求从a到b的最短路径
type
  Tvisited = array[1..Limit] of boolean;
var
  visited : Tvisited;
  i , min : longint;
begin
  fillchar(visited , sizeof(visited) , 0);
  for i := 1 to Limit do
   shortest := map[start , i];
  shortest[start] := 0;
  while not visited[stop] do
   begin
     min := 0;
     for i := 1 to Limit do
      if appeared and not visited then
       if (min = 0) or (shortest[min] > shortest) then
        min := i;

     visited[min] := true;

     for i := 1 to Limit do
      if appeared and not visited then
       if shortest[min] + map[min , i] < shortest then
        shortest := shortest[min] + map[min , i];
   end;
end;

procedure out;                    // 输出
begin
  assign(OUTPUT , OutFile); ReWrite(OUTPUT);
   writeln(shortest[stop]);
  Close(OUTPUT);
end;

Begin
  init;
  work;
  out;
End.
离线love_oi
只看该作者 1 发表于: 2005-11-09
安徽OI有一道啊。。。
离线amyhab
只看该作者 2 发表于: 2007-10-13
Vijos上的
To Be,Or not to be.That's a Question!!!!!!!
离线amyhab
只看该作者 3 发表于: 2007-10-13
可以去提交测试
To Be,Or not to be.That's a Question!!!!!!!
离线clwxzh57
只看该作者 4 发表于: 2007-10-13
谢谢
离线xyj
只看该作者 5 发表于: 2008-01-22
LZ的题目不全阿~
不过解答不错,谢谢啦
离线绝世衰神
只看该作者 6 发表于: 2008-02-01
又是最短路径
天生我材必有用
老鼠儿子会打洞
离线绝世衰神
只看该作者 7 发表于: 2008-02-01
看到它就头疼
天生我材必有用
老鼠儿子会打洞
离线yzasdf
只看该作者 8 发表于: 2008-02-05
谢谢
离线chenjiasheng
只看该作者 9 发表于: 2008-02-17
thanks
快速回复
限100 字节
 
上一个 下一个