题目描述

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

输入格式

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

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

输出格式

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


 

一道简单题, 用SPFA去更新最短路, 每次更新时, 即dis[y] > dis[x] + v, 点y的最短路就等于点x的最短路, 而当dis[y] = dis[x] + v时, 就说明该点产生了第二条最短路, 即点y最短路的条数加上点x最短路的条数。 即使当前不是最短路, 但是当更新到最短路时, 该最短路条数数组会重置成此时点x的最短路条数, 所以这个算法是正确的。

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
const int INF = 0x3f3f3f3f;
const int MAXN = 2e6 + 100;
const int MAXM = 3e3 + 10;

template < typename T > inline void read(T &x) {
    x = 0; T ff = 1, ch = getchar();
    while(!isdigit(ch)) {
        if(ch == '-') ff = -1;
        ch = getchar();
    }
    while(isdigit(ch)) {
        x = (x << 1) + (x << 3) + (ch ^ 48);
        ch = getchar();
    }
    x *=ff;
}

template < typename T > inline void write(T x) {
    if(x < 0) putchar('-'), x = -x;
    if(x > 9) write(x / 10);
    putchar(x % 10 + '0');
}
 
int n, m;
int dis[MAXN], vis[MAXN], a[MAXN]; 
int lin[MAXN], tot = 0;
struct edge {
    int y, next;
}e[MAXN];

inline void add(int xx, int yy) {
    e[++tot].y = yy;
    e[tot].next = lin[xx];
    lin[xx] = tot;
}

inline void SPFA() {
    memset(dis, 0x3f, sizeof(dis));
    memset(vis, false, sizeof(vis));
    queue < int > q; 
    dis[1] = 0; a[1] = 1;
    q.push(1);
    while(!q.empty()) {
        int x = q.front(); q.pop();
        vis[x] = false;
        for(int i = lin[x], y; i; i = e[i].next) {
            if(dis[y = e[i].y] > dis[x] + 1) {
                dis[y] = dis[x] + 1;
                a[y] = a[x]; 
                if(!vis[y]) {
                    vis[y] = true;
                    q.push(y);
                }
            }
            else if(dis[y] == dis[x] + 1) {
                a[y] += a[x];
                a[y] %= 100003;
            }
        }
    }
}

int main() {
    read(n); read(m);
    for(int i = 1; i <= m; ++i) {
        int u, v;
        read(u); read(v);
        if(u == v) continue;
        add(u, v);
        add(v, u);
    }
    SPFA();
    for(int i = 1; i <= n; ++i) {
        write(a[i]);
        puts("");
    }
    return 0;
}

 

版权声明:本文为AK-ls原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/AK-ls/p/11423504.html