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;
}
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,那就可以来回走。。。就有无线条了。。。 […]