P5001 魔法祝福

纯最短路模板题?

遇到这种题目就想到了BFS,但是状态会不会太多了啊?

我们可以借助NOIP2017PJT3“棋盘”的思想,用SPFA搞掉。

我们同样搞一个vis数组,dist数组,在队列里面自己搞个结构体或者pair。

然后就可以类似于SPFA那样写出来一个奇怪的程序了。

不知道为什么,我死活会T掉几个点只有80pts,看了标程也不知道我错在哪里,我太弱了。

日后如果这道题的题解丰富起来我应该会来补锅。

代码:(80pts的程序)

// luogu-judger-enable-o2
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>

const int maxn = 1000005;
struct Edges
{
    int next, to, t, k;
} e[maxn << 1];
int head[maxn], tot;
struct Nodes
{
    int u, z;
    Nodes(int u, int z): u(u), z(z){}
};
bool vis[maxn];
int dist[maxn];
int n, m, s, t;
int read()
{
    int ans = 0, s = 1;
    char ch = getchar();
    while(ch > '9' || ch < '0'){ if(ch == '-') s = -1; ch = getchar(); }
    while(ch >= '0' && ch <= '9') ans = ans * 10 + ch - '0', ch = getchar();
    return s * ans;
}
void link(int u, int v, int t, int k)
{
    e[++tot] = (Edges){head[u], v, t, k};
    head[u] = tot;
}
int main()
{
    n = read(), m = read(), s = read(), t = read();
    for(int i = 1; i <= m; i++)
    {
        int u = read(), v = read(), t = read(), k = read();
        link(u, v, t, k); link(v, u, t, k);
    }
    memset(dist, 0x3f, sizeof dist);
    std::queue<Nodes> q;
    dist[s] = 0;
    q.push(Nodes(s, 0)); vis[s] = true;
    while(!q.empty())
    {
        Nodes x = q.front(); q.pop(); vis[x.u] = false;
        int u = x.u, z = x.z;
        for(int i = head[u]; i; i = e[i].next)
        {
            int v = e[i].to;
            if(z >= e[i].k) continue;
            if(dist[u] + e[i].t < dist[v])
            {
                dist[v] = dist[u] + e[i].t;
                if(!vis[v])
                {
                    q.push(Nodes(v, z + 1));
                    vis[v] = true;
                }
            }
        }
    }
    if(dist[t] == 0x3f3f3f3f) printf("bao 0\n");
    else printf("%d\n", dist[t]);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Garen-Wang/p/9913028.html