本文主要是介绍最短路计数(Shortest Path Count),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
By Stockholm
最短路计数(Shortest Path Count)
来源:Luogu P1144
题目描述
给出一个 N 个顶点 M 条边的无向无权图,顶点编号为 1~N。问从
顶点 1 开始,到其他每个点的最短路有几条。
输入输出格式
输入格式:
输入第一行包含 2 个正整数 N,M,为图的顶点数与边数。
接下来 M 行,每行两个正整数 x, y,表示有一条顶点 x 连向顶点 y
的边,请注意可能有自环与重边。
输出格式:
输出包括 N 行,每行一个非负整数,第 i 行输出从顶点 1 到顶点 i 有
多少条不同的最短路,由于答案有可能会很大,你只需要输出 mod
100003 后的结果即可。如果无法到达顶点 i 则输出 0。输入输出样例
输入样例#1:
5 7
1 2
1 3
2 4
3 4
2 3
4 5
4 5
输出样例#1:
1 1 1 2 4
说明1 到 5 的最短路有 4 条, 分别为 2 条 1-2-4-5 和 2 条 1-3-4-5 (由于 4-5的边有 2 条)。
对于 20%的数据,N ≤ 100;
对于 60%的数据,N ≤ 1000;
对于 100%的数据,N<=1000000,M<=2000000。
思路
这个题用 SPFA 做,但是需要加一个计数操作,注意最后结果取模,以及如果一样的长度, 就需要在原来的基础上加上上一个节点累加器
中的记录数,SPFA 最好带上 SLF,这样快一些。
代码(C++)
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<deque>
using namespace std;
int i,j,m,n;
int head[1000001];
int us[1000001];
int t[1000001];int dis[1000001];
struct node
{
int yy;
struct node *nxt;
}a[4000005];
int r()
{
int aans=0;
char ch=getchar();
while(ch<'0'||ch>'9')
ch=getchar();
while(ch>='0'&&ch<='9')
{
aans*=10;
aans+=ch-'0';
ch=getchar();
}
return aans;
}int spfa(int x)
{
us[x]=1;
deque<int>q;
dis[x]=0;
q.push_front(x);
struct node *p;
while(!q.empty())
{
x=q.front();
p=&a[head[x]];
us[x]=0;
q.pop_front();
while(p->yy!=0)
{
if(dis[x]+1<dis[p->yy])
{
t[p->yy]=t[x]%100003;
dis[p->yy]=dis[x]+1;if(!us[p->yy])
{
if(q.empty()||dis[q.front()]>dis[p->yy])
q.push_front(p->yy);
else
q.push_back(p->yy);
us[p->yy]=1;
}
}
else if(dis[x]+1==dis[p->yy])
{t[p->yy]+=t[x];
t[p->yy]%=100003;}
p=p->nxt;
}
}
}
int main()
{
n=r(),m=r();
int x,y;for(i=1;i<=m;i++)
{
x=r(),y=r();
a[2*i-1].yy=y;
a[2*i-1].nxt=&a[head[x]];
head[x]=2*i-1;
a[2*i].yy=x;
a[2*i].nxt=&a[head[y]];
head[y]=2*i;
}
memset(dis,0x7f7f7f7f,sizeof(dis));
t[1]=1;
spfa(1);
for(i=1;i<=n;i++)
if(dis[i]!=0x7f7f7f7f)
cout<<t[i]<<endl;
else
cout<<0<<endl;
return 0;
}
这篇关于最短路计数(Shortest Path Count)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!