• 【洛谷P1346】电车【最短路】


    题目大意:

    题目链接:https://www.luogu.org/problemnew/show/P1346
    给出一个图,每条边有一个指定方向,但是如果想从这个点到达其它有通路但不是指定方向的点的话,就要改变指定方向并且花费为1。求从sstt的最小花费。


    思路:

    这个图没有边权。考虑用指定方向作为边权且跑最短路。
    由于如果要到的这个点是指定方向的点的话就不用花费,否则需要花费1,所以很容易想到将所有与这个点相连的点连边,若本来就是指定方向就边权为0,否则边权为1
    那么当走了一条不是指定方向的路之后,是否需要更改指定方向呢?
    很明显是不用的。
    假设我们走过了这个点之后不再回到这个点,那么是否更改就不会影响结果。
    假设我们走过了这个点之后再次回到这个点,那么相当于绕了一个环,在没有负边权的情况下,绕一个环肯定不会得到更优解,所以还不如不绕环,也就是还不如不回到这个点,即最优解的每个点最多只经过一次。
    nn很小,FloydFloyd即可。


    代码:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    int n,s,t,m,x,a[301][301];
    
    int main()
    {
        scanf("%d%d%d",&n,&s,&t);
        for (int i=1;i<=300;i++)
         for (int j=1;j<=300;j++) 
          if (i!=j) a[i][j]=99999999;  //初始化
        for (int i=1;i<=n;i++)
        {
            scanf("%d",&m);
            if(!m) continue;
            scanf("%d",&x);
            a[i][x]=0;  //存图
            m--;
            while (m--)
            {
                scanf("%d",&x);
                a[i][x]=1;
            }
        }
        for (int k=1;k<=n;k++)
         for (int i=1;i<=n;i++)
          for (int j=1;j<=n;j++)  //Floyd
           if (i!=j&&j!=k&&k!=i)
            a[i][j]=min(a[i][j],a[i][k]+a[k][j]);
        if (a[s][t]<99999999)printf("%d\n",a[s][t]);
         else printf("-1");
        return 0;
    }
    
  • 相关阅读:
    Python PyInstaller安装和使用教程(搬来的,嘻嘻)
    python 注册码永久性方法
    网上搬来的常用工具
    Pycharm控制台窗口怎样可以显示不同程序的运行结果
    php时间:获取上一个月,本月天数,下一个月
    thinkphp5 --接口实例
    浅谈 PHP 与手机 APP 开发
    php 对象的调用和引入
    php 超全局变量(整理)
    php 全局变量和超全局变量
  • 原文地址:https://www.cnblogs.com/hello-tomorrow/p/11998619.html
Copyright © 2020-2023  润新知