最短路计数

最短路计数_第1张图片

 题意:求1号点到每个点的最短路径的条数

分析:模板题,但要保证求的顺序是拓扑序,如果遇到的点的距离大于当前被更新点的距离就覆盖这个点之前的数据(比如如果先通过3-->2-->4,后来发现了另一条路3-->4),因为之前的数据不是最短路,如果准备走到的点已经有的距离是当前点的距离加1(假如原本已经有了1->3->4->6,d[6]=3,现在又发现了一条路1->3->5-6,  因为d[6]=3,现在是从5号点准备走到6号点,且d[5]+1=d[6],那么就直接更新cnt[6]=cnt[5]+cnt[6]),那么就说明这条路经也是最短路。

 最短路计数_第2张图片

 

#include


using namespace std;

const int N = 4e5+10,mod=100003;
int h[N],e[N],ne[N],idx;
int cnt[N];
int n,m;
int d[N];


void add(int a,int b)
{
    e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
void bfs()
{
    memset(d,0x3f,sizeof d);
    d[1]=0;
    cnt[1]=1;
    queue q;
    q.push(1);
    while(q.size())
    {
        auto t=q.front();
        q.pop();
        
        for(int i=h[t];~i;i=ne[i])
        {
            int j=e[i];
            if(d[j]>d[t]+1)//不是最短路径时候,更新一下
            {
                d[j]=d[t]+1;
                cnt[j]=cnt[t];
                q.push(j);
            }
            else if(d[j]==d[t]+1)//当前点是最短路径
            {
                cnt[j]=(cnt[j]+cnt[t])%mod;
            }
        }
    }
}

int main()
{
    cin>>n>>m;
    memset(h,-1,sizeof h);
    while(m--)
    {
        int a,b;
        cin>>a>>b;
        add(a,b);
        add(b,a);
    }
    
    bfs();
    
    for(int i=1;i<=n;i++) cout<

你可能感兴趣的:(提高,算法)