【洛谷P1144】最短路计数

不错的数字

1144 代表着新新志志()
主要是要强调一种思想 也就是我们如果看到疑似在最短路里跑DP的题目
那么 就在spfa/dijkstra里面加状态转移
下面直接看题

P1144 最短路计数

题目描述

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

输入格式

第一行包含 \(2\) 个正整数 \(N,M\),为图的顶点数与边数。

接下来 \(M\) 行,每行 \(2\) 个正整数 \(x,y\),表示有一条连接顶点 \(x\) 和顶点 \(y\) 的边,请注意可能有自环与重边。

输出格式

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

输入输出样例 #1

输入 #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\to 2\to 4\to 5\)\(2\)\(1\to 3\to 4\to 5\)(由于 \(4\to 5\) 的边有 \(2\) 条)。

对于 \(20\%\) 的数据,\(1\le N \le 100\)
对于 \(60\%\) 的数据,\(1\le N \le 10^3\)
对于 \(100\%\) 的数据,\(1\le N\le10^6\)\(1\le M\le 2\times 10^6\)

Solution

很明显就是算一个ans数组
然后当最短路更新的时候 更新ans数组
当刚好又遍历到一次最短路的时候 直接加
下面看代码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n,m,tot;
int x,y;
int head[5000005],ver[5000005],nex[5000005];
ll ans[1000005];
int d[1000005],v[1000005];
queue<int>q;
void add(int x,int y){
    ver[++tot]=y;
    nex[tot]=head[x];
    head[x]=tot;
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){
        scanf("%d%d",&x,&y);
        add(x,y);add(y,x);
    }
    memset(d,0x3f,sizeof(d));
    memset(v,0,sizeof(v));
    q.push(1);d[1]=0;
    v[1]=1;
    ans[1]=1;
    while(!q.empty()){
        int x=q.front();q.pop();
        v[x]=0;
        for(int i=head[x];i;i=nex[i]){
            int y=ver[i];
            if(d[y]>d[x]+1){
                d[y]=d[x]+1;
                ans[y]=ans[x];
                if(!v[y]){
                    v[y]=1;
                    q.push(y);
                }
            }
            else if(d[y]==d[x]+1){
                ans[y]+=ans[x];
                ans[y]%=100003;
            }
        }
    }
    for(int i=1;i<=n;i++){
        cout<<ans[i]<<endl;
    }
    system("pause");
    return 0;
}
//边权都为1的话 那么?
//跑spfa?
posted @ 2025-03-02 23:08  elainafan  阅读(67)  评论(0)    收藏  举报