• 3470. 【NOIP2013模拟联考8】最短路(path) (Standard IO)


    Description

    给定一个n个点m条边的有向图,有k个标记点,要求从规定的起点按任意顺序经过所有标记点到达规定的终点,问最短的距离是多少。

     

    Input

    第一行5个整数n、m、k、s、t,表示点个数、边条数、标记点个数、起点编号、终点编号。

    接下来m行每行3个整数x、y、z,表示有一条从x到y的长为z的有向边。

    接下来k行每行一个整数表示标记点编号。

     

    Output

    输出一个整数,表示最短距离,若没有方案可行输出-1。

    Solutions

    起点和每个标记点各跑一次SPFA,建立一个(k+1)*(k+1)的图,爆搜即可。

    代码

      1 type
      2   arr=record
      3     x,y,w,next:longint;
      4   end;
      5 var
      6   nm,n,m,k,s,t:longint;
      7   min,ans:int64;
      8   d:array [0..100001] of int64;
      9   ls,v,list:array [0..100001] of longint;
     10   a:array [0..100001] of arr;
     11   b:array [0..11] of longint;
     12   bo:array [0..11] of boolean;
     13   top:array [0..11,0..11] of int64;
     14 procedure init;
     15 var
     16   i,x:longint;
     17 begin
     18   readln(n,m,k,s,t);
     19   for i:=1 to m do
     20     begin
     21       readln(a[i].x,a[i].y,a[i].w);
     22       a[i].next:=ls[a[i].x];
     23       ls[a[i].x]:=i;
     24     end;
     25   for i:=1 to k do
     26     readln(b[i]);
     27 end;
     28 
     29 procedure spfa(x:longint);
     30 var
     31   i,j,k,h,t:longint;
     32 begin
     33   for i:=0 to 100001 do
     34     d[i]:=maxlongint*23333;
     35   fillchar(v,sizeof(v),0);
     36   fillchar(list,sizeof(list),0);
     37   h:=0; t:=1;
     38   v[x]:=1; list[1]:=x; d[x]:=0;
     39   repeat
     40     h:=h+1;
     41     j:=ls[list[h]];
     42     while j<>0 do
     43       begin
     44         with a[j] do
     45           begin
     46             if d[x]+w<d[y] then
     47               begin
     48                 d[y]:=d[x]+w;
     49                 if v[y]=0 then
     50                   begin
     51                     t:=t+1;
     52                     list[t]:=y;
     53                     v[y]:=1;
     54                   end;
     55               end;
     56             j:=next;
     57           end;
     58       end;
     59     v[list[h]]:=0;
     60   until h=t;
     61 end;
     62 
     63 procedure search(x:longint);
     64 var
     65   i:longint;
     66 begin
     67   if x=k+1 then
     68     begin
     69       for i:=1 to k do
     70         if bo[i] then exit;
     71       if ans<min then min:=ans;
     72       exit;
     73     end;
     74   for i:=1 to k+1 do
     75     if (top[x,i]>0) and bo[i] then
     76       begin
     77         bo[i]:=false;
     78         ans:=ans+top[x,i];
     79         search(i);
     80         bo[i]:=true;
     81         ans:=ans-top[x,i];
     82       end;
     83 end;
     84 
     85 procedure main;
     86 var
     87   i,j:longint;
     88 begin
     89   min:=maxlongint*23333; ans:=0;
     90   fillchar(top,sizeof(top),0);
     91   spfa(s);
     92   if k=0 then
     93     if d[t]<>0 then min:=d[t];
     94   for i:=1 to k do
     95     top[0,i]:=d[b[i]];
     96   for i:=1 to k do
     97     begin
     98       spfa(b[i]);
     99       top[i,k+1]:=d[t];
    100       for j:=1 to k do
    101         if i<>j then
    102           top[i,j]:=d[b[j]];
    103     end;
    104   fillchar(bo,sizeof(bo),true);
    105   for i:=1 to k do
    106     if b[i]=s then bo[i]:=false;
    107   search(0);
    108 end;
    109 
    110 begin
    111   init;
    112   main;
    113   if min=maxlongint*23333 then writeln('-1')
    114                           else writeln(min);
    115 end.
  • 相关阅读:
    致歉
    博客园上海俱乐部活动报道
    博客园手机版
    味道不错的NBearLite查询语法
    关于面向对象的讨论
    变形金刚皮肤
    准备在北京Tech·Ed上组织博客园聚会
    SVN&.NET
    博客园手机版功能更新
    最省时管理法:让你一天随意
  • 原文地址:https://www.cnblogs.com/zyx-crying/p/9431103.html
Copyright © 2020-2023  润新知