洛谷P1144 最短路计数bellman bfs

题目描述

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

输入格式
第一行包含22个正整数N,MN,M,为图的顶点数与边数。

接下来MM行,每行22个正整数x,yx,y,表示有一条顶点xx连向顶点yy的边,请注意可能有自环与重边。

输出格式
共NN行,每行一个非负整数,第ii行输出从顶点11到顶点ii有多少条不同的最短路,由于答案有可能会很大,你只需要输出ans \bmod 100003ansmod100003后的结果即可。如果无法到达顶点ii则输出00。

输入输出样例
输入 #1复制
5 7
1 2
1 3
2 4
3 4
2 3
4 5
4 5
输出 #1复制
1
1
1
2
4

解:

先进行最短路的更新,之后计算次数!


#include
#include
#include 
#include
#define INF 2147483640
#define mod 100003
using namespace std;
vector<int>g[2000005];
int n,m;
queue<int>dui;
int vis[2000005];
int cnt[1000005], d[1000005];
void bellman(){
     
    dui.push(1);
    cnt[1] = 1;
    while(!dui.empty()){
     
        int op = dui.front();
        dui.pop();
        vis[op] = 0;
        for(int i=0;i<g[op].size();i++){
     
            int to = g[op][i];
            
            if(d[op] < INF && d[op]+1<d[to]){
     
                d[to] = d[op] + 1;
                vis[to] = 1;
                dui.push(to);
            }
            if(d[op]+1 == d[to]){
     
                cnt[to] += cnt[op];//只有这里进行次数统计
                cnt[to] %= mod;
            }
        }
    }
    return;
}

int main() {
     
    scanf("%d%d",&n,&m);
    for(int i = 1;i<=m;i++){
     
        int a,b;
        scanf("%d%d",&a,&b);
        g[a].push_back(b);
        g[b].push_back(a);
        
    }
    
    for(int i=1;i<=n;i++){
     
        d[i] = INF;
    }
    d[1] = 0;
    bellman();
    for(int i=1;i<=n;i++){
     
        printf("%d\n",cnt[i]);
    }
    return 0;
}

你可能感兴趣的:(最短路,图论,bfs,bellman–ford,algorithm)