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。

  • 相关阅读:
    搜索回车跳转页面
    登录验证码
    【排序算法】排序算法之插入排序
    PAT 乙级 1044 火星数字 (20 分)
    PAT 甲级 1035 Password (20 分)
    PAT 甲级 1041 Be Unique (20 分)
    PAT 甲级 1054 The Dominant Color (20 分)
    PAT 甲级 1027 Colors in Mars (20 分)
    PAT 甲级 1083 List Grades (25 分)
    PAT 甲级 1005 Spell It Right (20 分)
  • 原文地址:https://www.cnblogs.com/yinyuqin/p/13849857.html
Copyright © 2011-2022 走看看