⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 servers.pas

📁 PASCAL光盘资料PASCAL光盘资料PASCAL光盘资料
💻 PAS
字号:
program ser;
{ This program for every server A computes the number of servers server A is interesting to, let us denote this set C(A). . The set C(A) is computed using Dijkstra algorithm. Notice that the set C(A) is a star set, and is closed under taking elements with smaller distance.We can stop Dijkstra when we reach an element that not belongs to C(A). An element X does not belong to C(A) if ther exist a server with higher rankthat A, that is nearer. In Dijkstra we know distance from A to X, so we  nead to compute for every server a distance to a nearest server with at least rank r for every r. These distances can be computed by runing Dijkstra 9 times, in every time starting from servers with ranks greaterthen some r, 1<=r<10.} const
  MAXN = 100000;
  MAXD = 1000 * MAXN + 1;
  MAXSUMMUL = 30;type
  inheapt = record
    nr : longint;
    key : longint;
  end;

  connt = record
    nr : longint;
    t : longint;
  end;
var
  // The heap.
  inheap : array[1..MAXN] of inheapt;
  heap: array[1..MAXN] of longint;
  heapn : longint;

  // Here we remember visited servers
  visited : array[1..MAXN] of longint;

  // connections betwen servers
  connn : array[1..MAXN] of longint;
  conn: array[1..MAXN,1..10] of connt;

  rank : array[1..MAXN] of longint;

  // distance to nearest server with rank at least k, where k is second index
  nearestr : array[1..MAXN,1..10] of longint;
  
  n, m, r: longint;
  // num - here we count servers
  num : longint;
// Init heap
procedure makeemptyheap(n:longint);
var
  i : longint;
begin
  for i := 1 to n do
  begin
    heap[i] := i;
    inheap[i].nr := i;
    inheap[i].key := MAXD;
  end;
  heapn := n;
end;

// repair heap upwords
procedure up(i:longint);
var
  t : longint;
begin
    while (i<>1) and (inheap[heap[i]].key < inheap[heap[i shr 1]].key) do
    begin
      t := heap[i];
      heap[i] := heap[i shr 1];
      heap[i shr 1] := t;
      inheap[heap[i shr 1]].nr := i shr 1;
      inheap[heap[i]].nr := i;
      i := i shr 1;
    end;
end;
// decrease a key in the heap
procedure decreasekey(nr : longint; dk : longint);
begin
  if dk < inheap[nr].key then
  begin
    inheap[nr].key := dk;
    up(inheap[nr].nr);
  end;
end;

// insert an element into heaopprocedure insert(nr : longint; key : longint);
begin
  inc(heapn);
  heap[heapn] := nr;
  inheap[nr].nr := heapn;
  inheap[nr].key := key;
  up(heapn);
end;

// extracts minimal element from the heapprocedure extractmin(var el:longint; var key : longint);
var
  i, t, l, r: longint;
  smallest: longint;
begin
  el := heap[1];
  key := inheap[heap[1]].key;
  heap[1] := heap[heapn];
  inheap[heap[1]].nr := 1;
  dec(heapn);

  smallest := 1;
  repeat
    i := smallest;
    l := 2*i;
    r := 2*i + 1;
    if (l<=heapn) and (inheap[heap[l]].key < inheap[heap[i]].key) then
       smallest := l
    else
       smallest := i;
    if (r<=heapn) and (inheap[heap[r]].key < inheap[heap[smallest]].key) then
       smallest := r;
    if smallest <> i then
    begin
      t := heap[i];
      heap[i] := heap[smallest];
      heap[smallest] := t;
      inheap[heap[i]].nr := i;
      inheap[heap[smallest]].nr := smallest;
    end;
  until smallest = i;
end;

procedure inc_num(a : longint);begin  inc(num, a);  if (num > MAXSUMMUL*n) then begin    writeln('Total sum too big: ', num);    halt(1);  endend; // connect two serversprocedure connect(a,b,t:longint);
begin
  inc(connn[a]);
  conn[a,connn[a]].nr := b;
  conn[a,connn[a]].t := t;
end;

// This procedure computes the nearest servers with rank greater then rr.

procedure computenearest;
var
  rr,i,j,key : longint;
begin
  for rr := 1 to 9 do
  begin
    makeemptyheap(n);
    for i := 1 to n do
      if rank[i] > rr then
      begin
        decreasekey(i,0);
      end;
    while heapn > 0 do
    begin
      extractmin(i,key);
      nearestr[i,rr] := key;
      for j := 1 to connn[i] do
      begin
        decreasekey(conn[i,j].nr, key + conn[i,j].t );
      end;
    end;
  end;
end;

// computes the size of a set C(nr)

procedure reaches(nr: longint);
var
  i, j : longint;
  key : longint;
  ar : longint;
begin
  heapn := 0;
  ar := rank[nr];
  if ar = r then
    inc_num(n)
  else
  begin
    insert(nr,0);
    visited[nr]:=nr;
    while (heapn > 0) do
    begin
      extractmin(i,key);
      if key < nearestr[i,ar] then
      begin
        inc_num(1);
        for j := 1 to connn[i] do
        begin
          if visited[conn[i,j].nr] <> nr then
          begin
            insert(conn[i,j].nr, key + conn[i,j].t );
            visited[conn[i,j].nr] := nr;
          end
          else
            decreasekey(conn[i,j].nr, key + conn[i,j].t );
        end;
      end;
    end;
  end;
end;


var
  i : longint;
  a,b,t : longint;
begin
  num := 0;
  readln(n,m);
  r := 0;  for i := 1 to n do
  begin
    readln(rank[i]);
    if r < rank[i]      then r := rank[i];  end;
  for i := 1 to m do
  begin
    readln(a,b,t);
    connect(a,b,t);
    connect(b,a,t);
  end;

  computenearest;

  for i := 1 to n do
  begin
    reaches(i);
  end;  writeln(num);
end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -