• JZOJ3470 最短路


    Description

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

    Input

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

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

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

    Output

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

    Sample Input

      3 3 2 1 1
      1 2 1
      2 3 1
      3 1 1
      2
      3

    Sample Output

      3

    【样例解释】
      路径为1->2->3->1。

    Data Constraint

      20%的数据n<=10。

      50%的数据n<=1000。

      另有20%的数据k=0。

      100%的数据n<=50000,m<=100000,0<=k<=10,1<=z<=5000。

     

    Solution

      对每个特殊点跑一次spfa,因为k非常小,所以dfs特殊点得顺序。

     1 #include <cstdio>
     2 using namespace std;
     3 struct arr 
     4 { 
     5     int x,y,next;
     6     long long w;
     7 };
     8 arr edge[200000];
     9 int ls[200000],dis[60000],n,m,d[200000],k,a,b,s[20];
    10 bool f[20];
    11 long long dist[12][60000],min,cc;
    12 int tt(int y,long long w,int c)
    13 {
    14     if (y==k)
    15     {
    16         if (w+dist[c][b]<min&&dist[c][b]!=cc)
    17             min=w+dist[c][b];
    18         return 0;
    19     }
    20     for (int i=2;i<=k+1;i++)
    21         if (f[i])
    22         {
    23             f[i]=false;
    24             if (dist[c][s[i]]!=c)
    25                 tt(y+1,w+dist[c][s[i]],i);
    26             f[i]=true;
    27         }
    28 }
    29 int ss(int x,int y)
    30 {
    31     int h=0,t=1;
    32     d[1]=x;
    33     for (int i=1;i<=n;i++)
    34         dist[y][i]=0xffffffff;
    35     dist[y][x]=0;
    36     while (h<=t)
    37     {
    38         int i=ls[d[++h]];
    39         while (i!=0)
    40         {
    41             if (dist[y][edge[i].x]+edge[i].w<dist[y][edge[i].y])
    42             {
    43                 dist[y][edge[i].y]=dist[y][edge[i].x]+edge[i].w;
    44                 d[++t]=edge[i].y;
    45             }
    46             i=edge[i].next;
    47         }
    48     }
    49 }
    50 int main()
    51 {
    52     scanf("%d%d%d%d%d",&n,&m,&k,&a,&b);
    53     for (int i=1;i<=m;i++)
    54     {
    55         scanf("%d%d%d",&edge[i].x,&edge[i].y,&edge[i].w);
    56         edge[i].next=ls[edge[i].x];
    57         ls[edge[i].x]=i;
    58     }
    59     ss(a,1);
    60     for (int i=2;i<=k+1;i++)
    61     {
    62         scanf("%d",&s[i]);
    63         ss(s[i],i);
    64     }
    65     min=0xffffffff;
    66     cc=0xffffffff;
    67     f[1]=false;
    68     for (int i=2;i<=k+1;i++)
    69     {
    70         for (int j=2;j<=k+1;j++)
    71             f[j]=true;
    72         f[i]=false;
    73         tt(1,dist[1][s[i]],i);
    74     }
    75     if (k==0) min=dist[1][b];
    76     if (min==cc) printf("-1");
    77     else
    78     printf("%lld",min);
    79 }
    View Code
  • 相关阅读:
    Python解释器的安装 安装IDE工具 pycharm
    推荐一些基础知识,希望对大家了解python语言及计算机有一些帮助!
    Typora 技巧
    js 与或运算符 || && 妙用
    数据类型和Json格式
    从事前端开发必须要了解的CSS原理
    CSS浏览器兼容
    用jQuery Mobile创建Web App
    让你的网站变成响应式的3个简单步骤
    CSS BFC hasLayout模型
  • 原文地址:https://www.cnblogs.com/Tokisaki-Kurumi/p/9432325.html
Copyright © 2020-2023  润新知