洛谷 P1144 最短路計數 題解

P1144 最短路計數

題目描述

給出一個\(N\)個頂點\(M\)條邊的無向無權圖,頂點編號爲\(1-N\)。問從頂點\(1\)開始,到其餘每一個點的最短路有幾條。node

輸入格式

第一行包含\(2\)個正整數\(N,M\),爲圖的頂點數與邊數。ios

接下來\(M\)行,每行\(2\)個正整數\(x,y\),表示有一條頂點\(x\)連向頂點\(y\)的邊,請注意可能有自環與重邊。spa

輸出格式

共NN行,每行一個非負整數,第ii行輸出從頂點11到頂點ii有多少條不一樣的最短路,因爲答案有可能會很大,你只須要輸出\(ans \bmod 100003\)後的結果便可。若是沒法到達頂點\(i\)則輸出\(0\)code

輸入輸出樣例

輸入 #1get

5 7
1 2
1 3
2 4
3 4
2 3
4 5
4 5string

輸出 #1it

1
1
1
2
4io

說明/提示

\(1\)\(5\)的最短路有\(4\)條,分別爲\(2\)\(1-2-4-5\)\(2\)\(1-3-4-5\)(因爲\(4-5\)的邊有\(2\)條)。class

對於\(20\%\)的數據,\(N ≤ 100\)stream

對於\(60\%\)的數據,\(N ≤ 1000\)

對於\(100\%\)的數據,\(N<=1000000,M<=2000000\)

【思路】

最短路 , dijkstra

【題目大意】

從1到每個點的最短路有多少條

【核心思路】

最短路有多少條?
徹底能夠在dijkstra或者SPFA的過程當中求出來的
由於在鬆弛操做的時候
用y到x的邊去鬆弛
若是這條邊替換上去會使1到x的距離更近
那這個時候x的答案就會變爲鬆到他y的最短路的個數
若是這條邊替換上去和原來同樣
那就是目前看來能夠當作最短路
在x原來最短路個數的基礎上加上到點y最短路的個數就能夠了

【完整代碼】

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>

using namespace std;

int read()
{
    int sum = 0,fg = 1;
    char c = getchar();
    while(c < '0' || c > '9')
    {
        if(c == '-')fg = -1;
        c = getchar();
    }
    while(c >= '0' && c <= '9')
    {
        sum = sum * 10 + c - '0';
        c = getchar();
    }
    return sum * fg;
}
const int Max = 2000006;
const int mo = 100003;
struct node
{
    int y,ne;
}a[Max << 1];
int head[Max >> 1],sum = 0;

void add(int x,int y)
{
    a[++ sum].y = y;
    a[sum].ne = head[x];
    head[x] = sum;
}

struct point
{
    int x;
    int w;
    bool operator < (const point xx) const
    {
        return xx.w < w;
    }
};
int dis[Max >> 1];
priority_queue<point>q;
int ans[Max >> 1];
bool use[Max >> 1];
void dj()
{
    memset(dis,0x3f,sizeof(dis));
    dis[1] = 0;
    ans[1] = 1;
    q.push((point){1,0});
    while(!q.empty())
    {
        point qwq = q.top();
        q.pop();
        int x = qwq.x,w = qwq.w;
        if(use[x] == true)
            continue;
        else
            use[x] = true;
        for(register int i = head[x];i != 0;i = a[i].ne)
        {
            int awa = a[i].y;
            if(dis[awa] > dis[x] + 1)
            {
                dis[awa] = dis[x] + 1;
                ans[awa] = ans[x];
                if(use[awa] == false)
                    q.push((point){awa,dis[awa]});
            }
            else
            if(dis[awa] == dis[x] + 1)
            {
                ans[awa] += ans[x];
                ans[awa] %= mo;
            }
        }
    }
}

int main()
{
    int n = read(),m = read();
    for(register int i = 1;i <= m;++ i)
    {
        int x = read(),y = read();
        add(x,y);
        add(y,x);
    }
    dj();
    for(register int i = 1;i <= n;++ i)
        cout << ans[i] << endl;
    return 0;
}
相關文章
相關標籤/搜索