『例题题解』最短路计数

题目描述

给出一个N个顶点M条边的无向无权图,顶点编号为1−N。问从顶点1开始,到其他每个点的最短路有几条。

Solution

从最基础的DJ思考:
迭代式进行迭代定然满足 d [ p ] + v a l < d [ n p ] d[p]+val<d[np] d[p]+val<d[np]
其中 p p p表示当前循环的点, n p np np表示与 p p p相连的新枚举的点。
因此我们在这一处转移做变化:
d [ p ] + v a l = d [ n p ] d[p]+val=d[np] d[p]+val=d[np]时,累加答案。
d [ p ] + v a l = d [ n p ] d[p]+val=d[np] d[p]+val=d[np]时,更新答案和最短路。
代码如下:

#include
using namespace std;
const int N=2000000;
const int P=100003 ;
int n,m;
int v[N],d[N],ans[N];
vector<int>a[N];
inline void read(int &s)
{
    char c=getchar();s=0;
    while (c<'0' || c>'9') c=getchar();
    while (c>='0' && c<='9') s=s*10+c-48,c=getchar();
}
int main(void)
{
    read(n),read(m);
    for (int i=1;i<=m;++i)
    {
    	int x,y;
    	read(x),read(y);
    	a[x].push_back(y);
    	a[y].push_back(x);
    }
    
    memset(v,0,sizeof(v));
    memset(d,30,sizeof(d));
    d[1]=0,ans[1]=1;
    priority_queue< pair<int,int> > q;
    q.push(make_pair(0,1));
    while (q.size())
    {
        int p=q.top().second;
        q.pop();
        if (v[p]) continue;
        v[p]=1;
        for (int i=0;i<a[p].size();++i)
        {
            int np=a[p][i];
            if (d[np]==d[p]+1) ans[np]=(ans[p]+ans[np])%P;
            if (d[np]>d[p]+1) d[np]=d[p]+1,ans[np]=ans[p];
            q.push(make_pair(-d[np],np));
        }
    }
    for (int i=1;i<=n;++i) printf("%d\n",ans[i]);
    return 0;
} 

你可能感兴趣的:(图论)