最短路计数

来源:互联网 发布:井冈山大学网络 编辑:程序博客网 时间:2024/06/05 08:22

题目描述

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

输入输出格式

输入格式:

输入第一行包含2个正整数N,M,为图的顶点数与边数。
接下来M行,每行两个正整数x, y,表示有一条顶点x连向顶点y的边,请注意可能有自环与重边。

输出格式:

输出包括N行,每行一个非负整数,第i行输出从顶点1到顶点i有多少条不同的最短路,由于答案有可能会很大,你只需要输出mod 100003后的结果即可。如果无法到达顶点i则输出0。

输入输出样例

输入样例#1:

5 71 21 32 43 42 34 54 5

输出样例#1:

11124

说明

1到5的最短路有4条,分别为2条1-2-4-5和2条1-3-4-5(由于4-5的边有2条)。
对于20%的数据,N ≤ 100;
对于60%的数据,N ≤ 1000;
对于100%的数据,N ≤ 100000,M ≤ 200000。
dp的思路,cut[i] 记录点 i 最短路的方案数,如果有一种从 f 点更新比当前到点 t 所需长度更短的方案,那么 cut[t] = cut[f] , 如果有一种从 f 点更新比当前到点 t 所需长度相等的方案那么 cut[t] += cut[f],初始值为起点 s 的 cut[s] = 1 。
代码如下

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<queue>using namespace std;const int size = 2000010;const int mod = 100003;int head[size],next[size],dist[size];struct dc{    int t,d;}l[size];int tot = 1;void build(int f,int t,int d){    l[tot].t = t;    l[tot].d = d;    next[tot] = head[f];    head[f] = tot ++;}int n,m;queue < int > q;int cut[size];bool use[size];void spfa(){    dist[1] = 0;    use[1] = 1;    cut[1] = 1;    q.push(1);    while(!q.empty())    {        int f = q.front();        q.pop();        use[f] = 0;        for(int i = head[f] ; i ; i = next[i])        {            int t = l[i].t;            if(dist[t] == dist[f] + l[i].d)                cut[t] += cut[f] % mod , cut[t] %= mod;            else if(dist[t] > dist[f] + l[i].d)            {                cut[t] = cut[f] % mod;                dist[t] = dist[f] + l[i].d;                if(!use[t])                {                    use[t] = 1;                    q.push(t);                }            }        }    }}int main(){    scanf("%d%d",&n,&m);    for(int i = 1 ; i <= m ; i ++)    {        int f,t;        scanf("%d%d",&f,&t);        build(f,t,1);        build(t,f,1);    }    for(int i = 1 ; i <= n ; i ++)        dist[i] = 2147483641;    spfa();    for(int i = 1 ; i <= n ; i ++)        if(dist[i] == 2147483641)            puts("0");        else            printf("%d\n",cut[i]%mod);    return 0;}
0 0