P1613 跑路
题目重点
1.有向图
2.跑的 路径 最少能被分割为几段长度为\(2^k\),因为每段路长度为\(1km\)
3.有自边
算法设计思考
1.在无背景、k=0的情况下,这题就是一个普通的dp(即floyd)
2.加上了约束条件,当某两个点的距离为\(2^k\)时,可以在1s内到达
3.相当于每走一段路花1s,当条件2成立时,两点间行动只花1s
4.由于存在自边和环(可能),某两个点间的距离可能不是固定的
5.当两个点的可能距离为4时,一定存在中间点使得互相距离为2
总结
1.因此我们可以从\(1\)遍历到\(32\),判断两个点间可不可能有这样的距离,如果有,那么这两个点间的传送距离变为一
code
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll pass[55][55][35]={0};//pass[i][j][k]代表从i点到j点存不存在2^k距离
ll dis[55][55];//代表实际传送距离
int main()
{
    memset(dis,0x3f3f3f,sizeof(dis));
    ll  n,m;
    cin>>n>>m;
    for(int i=1;i<=m;i++)
    {
        ll x,y;
        cin>>x>>y;
        pass[x][y][0]=1;
        dis[x][y]=1;
    }
    for(int k=1;k<=32;k++)
        for(int d=1;d<=n;d++)
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++)
                    dis[i][j]=(pass[i][j][k]=(pass[i][d][k-1]&pass[d][j][k-1])|(pass[i][j][k]))?1:min(dis[i][j],dis[i][d]+dis[d][j]);
    cout<<dis[1][n];
    return 0;
}
 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号