zoukankan      html  css  js  c++  java
  • 洛谷 P1613 跑路(Floyd,倍增)&& 【模板】 Floyd

    传送门


    解题思路

    g[i][j][k]表示i到j这个点有没有长度为2^k的路径,若有为1,若没有为0。答案可以由g[i][x][k-1]&&g[x][j][k-1]更新(Floyd传递闭包)。

    倍增求一遍后,把所有g[i][j][k] = 1 的 i j之间连一条长度为1的边(因为可以一步到达)。

    然后在新图上做一遍最短路求一遍即可。

    小小的眼睛里充满了大大的疑惑:

    • 与dp有啥关系……冲着dp标签去的
    • 只是一道绿题?感觉某些蓝题都比这个简单(看来我还是太菜了)

    AC代码

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cmath>
     4 #include<cstdio>
     5 #include<cstring>
     6 using namespace std;
     7 int n,m,dis[55][55];
     8 bool g[55][55][70];
     9 int main()
    10 {
    11     memset(dis,0x3f,sizeof(dis));
    12     cin>>n>>m;
    13     for(int i=1;i<=m;i++){
    14         int u,v;
    15         scanf("%d%d",&u,&v);
    16         g[u][v][0]=1;
    17         dis[u][v]=1;
    18     }
    19     for(int lxl=1;lxl<=64;lxl++){
    20         for(int i=1;i<=n;i++){
    21             for(int j=1;j<=n;j++){
    22                 for(int k=1;k<=n;k++){
    23                     g[i][j][lxl]=max(g[i][j][lxl],g[i][k][lxl-1]&&g[k][j][lxl-1]);
    24                 }
    25                 if(g[i][j][lxl]) dis[i][j]=1;
    26             }
    27         }
    28     }
    29     for(int k=1;k<=n;k++){
    30         for(int i=1;i<=n;i++){
    31             for(int j=1;j<=n;j++){
    32                 dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
    33             }
    34         }
    35     }
    36     cout<<dis[1][n];
    37     return 0;
    38 }

    //发现博客里没有Floyd的题?那就当个Floyd板子吧QAQ

    //那既然是板子,就补充一句,Floyd一定要先枚举中间点k。

  • 相关阅读:
    全程软件测试_项目启动
    全程软件测试_规范测试过程
    python_json常用的方法
    python_eval的用法
    python_判断字符串编码的方法
    python_Notepad++编码集的说明
    python_编码集的介绍
    初识HTML
    mysql学习目录
    python学习目录
  • 原文地址:https://www.cnblogs.com/yinyuqin/p/13849857.html
Copyright © 2011-2022 走看看