Luogu P1613 Problem Solving Report

P1613 Running away

Topic description

Xiao \(A\) 's work is not only cumbersome, but also has strict regulations, requiring Xiao \(A\ ) to arrive at the company before \(6:00\ ) every morning , otherwise the salary will be reset to zero this month. But Xiao \(A\) has the bad problem of staying in bed. So in order to keep his salary, Xiao \(A\) bought a very good space runner, which can run \(2^k\) kilometers per second ( \(k\) is any natural number). Of course, this machine is stored in \(long\) \(int\) , so the total running length cannot exceed \(max\) \(long\) \(int\) kilometers. The road from the home of the small \(A\) to the company can be regarded as a directed graph, the home of the small \(A\) is the point \(1\) , the company is the point \(n\) , and the length of each edge is One thousand meters. Xiao \(A\) wants to wake up as late as possible every day, so let you help him calculate, he needs at least a few seconds to arrive at the company. The data guarantees that there is at least one path from \(1\) to \(n\) .

Input and output format

Input format:

The first line contains two integers \(n\) , \(m\) , which represent the number of points and the number of sides.

The next m lines each have two numbers \(u\) , \(v\) , representing an edge from \(u\) to \(v\) .

Output format:

One number per line representing the minimum number of seconds to the company.

illustrate

\(50\) % of the data satisfy the optimal solution path length \(<=1000\) ;

\(100\) % of the data satisfy \(n<=50\) , \(m<=10000\) , the optimal solution path length \(<=\) \(max\) \(long\) \( int\) .


First of all, you must ensure that your language level is good. If this ghost machine runs \(2^kkm\) per second , it will run for just that long, neither more nor less.

So doesn't it mean that only a chain with a length of \(2^kkm\) is a valid edge?

We connect all valid edges and run the shortest path.

How to find the effective edge?

\(2^k?\) Did you think of anything?

\(2^k=2^{k-1}+2^{k-1}?\)

Yes, it is multiplied!

Let \(g[u][v][j]\) represent the presence or absence of an edge of length \(2^j\) from point \(u\) to point \(v\) .

When \(g[u][k][j-1]\) and \(g[k][v][j-1]\) exist at the same time,
\(g[u][v][j] \) exists. ( \(k\) is one dimension of the enumeration)


#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int N=52;
int g[N][N][70],n,m;
//g[i][j][k]表示i点到j点存在边权为2^k的路
int g0[N][N];
int read()
{
    int x=0;char c=getchar();
    while(c<'0'||c>'9') c=getchar();
    while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}
    return x;
}
queue <int > q;
int used[N],dis[N];
void spfa()
{
    memset(used,0,sizeof(used));
    used[1]=1;
    memset(dis,0x3f,sizeof(dis));
    dis[1]=0;
    q.push(1);
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        used[u]=0;
        for(int v=1;v<=n;v++)
            if(g0[u][v]&&dis[v]>dis[u]+g0[u][v])
            {
                dis[v]=dis[u]+g0[u][v];
                if(!used[v])
                {
                    used[v]=1;
                    q.push(v);
                }
            }
    }
}

int main()
{
    memset(g,0,sizeof(g));
    memset(g0,0,sizeof(g0));
    n=read(),m=read();
    int u,v;
    for(int i=1;i<=m;i++)
    {
        u=read(),v=read();
        g[u][v][0]=1;
        //f[u][v][0]=v;
    }
    for(int j=1;j<=64;j++)
        for(int k=1;k<=n;k++)
            for(u=1;u<=n;u++)
                for(v=1;v<=n;v++)
                    if(g[u][k][j-1]&&g[k][v][j-1])
                        g[u][v][j]=1;
    for(u=1;u<=n;u++)
        for(v=1;v<=n;v++)
            for(int j=0;j<=64;j++)
                if(g[u][v][j])
                {
                    g0[u][v]=1;
                    break;
                }
    spfa();
    printf("%d\n",dis[n]);
    return 0;
}

2018.5.2

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325382380&siteId=291194637