洛谷---P1144 最短路計數---BFS

題目描述

給出一個NNN個頂點MMM條邊的無向無權圖,頂點編號爲1−N1-N1N。問從頂點111開始,到其他每個點的最短路有幾條。

輸入格式

第一行包含222個正整數N,MN,MN,M,爲圖的頂點數與邊數。

接下來MMM行,每行222個正整數x,yx,yx,y,表示有一條頂點xxx連向頂點yyy的邊,請注意可能有自環與重邊。

輸出格式

NNN行,每行一個非負整數,第iii行輸出從頂點111到頂點iii有多少條不同的最短路,由於答案有可能會很大,你只需要輸出ans mod 100003 ans \bmod 100003ansmod100003後的結果即可。如果無法到達頂點iii則輸出000

輸入輸出樣例

輸入 #1 複製
5 7
1 2
1 3
2 4
3 4
2 3
4 5
4 5
輸出 #1 複製
1
1
1
2
4

說明/提示

111555的最短路有444條,分別爲2221−2−4−51-2-4-512452221−3−4−51-3-4-51345(由於4−54-545的邊有222條)。

對於20%20\%20%的數據,N≤100N ≤ 100N100

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

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

思路

  1. 利用廣搜的特性,第一個訪問到的點的距離必爲最短距離,固定最短距離,用於後面對比不同路徑到達該點時比較距離長度。
  2. 當前路徑個數 = 所有源的路徑個數的和

實現代碼

#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
using namespace std;

const int maxn = 1e6 + 5;
const int mod = 1e5 + 3;
const int inf = 0x3f3f3f3f;

int dis[maxn], cal[maxn], vis[maxn];
vector<int> edge[maxn];

void bfs() {
	memset(dis, inf, sizeof(dis));
	memset(cal, 0, sizeof(cal));
	memset(vis, 0, sizeof(vis));
	vis[1] = 1, cal[1] = 1;
	queue<int> q; q.push(1);
	while (q.size()) {
		int now = q.front(); q.pop();
		for (int i = 0; i < edge[now].size(); i++) {
			int to = edge[now][i];
			// 固定最短路距離
			if (!vis[to]) dis[to] = dis[now] + 1, vis[to] = 1, q.push(to);		
			// 若從 now 點到 to 的距離等於最短路距離,則把now點的所有路徑加到 to 中
			if (dis[to] == dis[now] + 1) cal[to] = (cal[to] + cal[now]) % mod;	
		}
	}
}

int main() { 
	ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
	int n, m, u, v;
	cin >> n >> m;
	for (int i = 1; i <= m; i++) {
		cin >> u >> v;
		edge[u].push_back(v);
		edge[v].push_back(u);
	}
	bfs();
	for (int i = 1; i <= n; i++) {
		if (cal[i] == inf) cout << 0 << endl;
		else cout << cal[i] % mod << endl;
	}
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章