1. 题目

传送门= ̄ω ̄=

2. 题解

网上很多人用的是下面这种代码。可以 ac,但其实是错误的。

错误代码(其实是我一开始是用的这个代码):

#include <bits/stdc++.h>
using namespace std;
int n,m,head[1000005],to[4000005],nxt[4000005],gsize,dis[1000005],ans[1000005];
bool book[1000005];
queue<int> que;
void adde(int u,int v){to[gsize]=v,nxt[gsize]=head[u],head[u]=gsize++;}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)head[i]=-1,dis[i]=100000000;
    for(int i=1,u,v;i<=m;i++)scanf("%d%d",&u,&v),adde(u,v),adde(v,u);
    dis[1]=0,que.push(1),ans[1]=book[1]=1;
    while(!que.empty())
    {
        int f=que.front();que.pop(),book[f]=0;
        for(int i=head[f];i!=-1;i=nxt[i])
            if(dis[f]+1<dis[to[i]])
            {
                dis[to[i]]=dis[f]+1,ans[to[i]]=ans[f];
                if(!book[to[i]])que.push(to[i]),book[to[i]]=1;
            }
            else if(dis[f]+1==dis[to[i]])ans[to[i]]=(ans[to[i]]+ans[f])%100003;
    }
    for(int i=1;i<=n;i++)printf("%d\n",ans[i]);
    return 0;
}

这样虽然可以 AC,但是其实是数据水了。
不信你去做这题:
https://cn.vjudge.net/problem/UESTC-1147

正确做法:
1. 跑一边 spfa,计算出源点到其他点的最短路径长度。
2. 跑一遍记忆化搜索,得到答案。
代码如下:

#include <bits/stdc++.h>
using namespace std;
int n,m,head[1000005],to[4000005],nxt[4000005],gsize,dis[1000005],ans[1000005];
bool book[1000005];
queue<int> que;
void adde(int u,int v){to[gsize]=v,nxt[gsize]=head[u],head[u]=gsize++;}
int dfs(int u)
{
    if(ans[u])return ans[u];
    for(int i=head[u];i!=-1;i=nxt[i])
        if(dis[u]-1==dis[to[i]])ans[u]=(ans[u]+dfs(to[i]))%100003;
    return ans[u];
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)head[i]=-1,dis[i]=INT_MAX;
    for(int i=1,u,v;i<=m;i++)scanf("%d%d",&u,&v),adde(u,v),adde(v,u);
    dis[1]=0,que.push(1),book[1]=1;
    while(!que.empty())
    {
        int f=que.front();que.pop(),book[f]=0;
        for(int i=head[f];i!=-1;i=nxt[i])
            if(dis[f]+1<dis[to[i]])
            {
                dis[to[i]]=dis[f]+1;
                if(!book[to[i]])que.push(to[i]),book[to[i]]=1;
            }
    }
    ans[1]=1;for(int i=1;i<=n;i++)printf("%d\n",dfs(i));
    return 0;
}
分类: 文章

XZYQvQ

炒鸡辣鸡的制杖蒟蒻一枚QvQ

3 条评论

juruo-oier · 2018年9月5日 1:22 下午

为啥我觉得您写的是广搜而不是 spfa(可能我太蒟了)

    XZYQvQ · 2018年9月5日 6:33 下午

    边长都是 1 的图跑 spfa 和跑 bfs 不是完全相同的东西吗=。=
    复杂度都是一样的

【题解】秋实大哥带我飞 – K-XZY · 2017年5月10日 7:40 下午

[…] 同 http://k-xzy.cf/?p=1227 跑一遍 spfa 再跑记忆化搜索。 至于什么情况下存在无限条最短路。。。 其实就是最短路径上存在一条边的花费为 0,那就可以来回走。。。就有无线条了。。。 […]

发表回复

Avatar placeholder

您的邮箱地址不会被公开。 必填项已用 * 标注