国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

[Daimayuan] 最短路計數(shù)(C++,DP,圖論)

這篇具有很好參考價值的文章主要介紹了[Daimayuan] 最短路計數(shù)(C++,DP,圖論)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

題目描述

給出一個 N N N 個頂點 M M M 條邊的無向無權(quán)圖。

問從頂點 1 1 1 開始,到其他每個點的最短路有幾條。

輸入格式

1 1 1 行包含兩個正整數(shù) N N N, M M M。

接下來 M M M 行,每行兩個正整數(shù) x , y x,y x,y表示存在一條由頂點 x x x 到頂點 y y y 的邊。(可能存在重邊和自環(huán))

輸出格式

輸出 N N N 行,每行一個非負(fù)整數(shù)。

i i i 行輸出從頂點 1 1 1 到頂點 i i i 的不同最短路個數(shù)。

由于數(shù)據(jù)可能很大,你只需要輸出 a n s ? m o d ? 100003 ans\ mod\ 100003 ans?mod?100003 的結(jié)果。

若頂點 1 1 1 不能到達頂點 i i i,請輸出 0 0 0。

樣例輸入
5 7
1 2
1 3
2 4
3 4
2 3
4 5
4 5
樣例輸出
1
1
1
2
4
數(shù)據(jù)范圍

1 ≤ N ≤ 1 0 6 1≤N≤10^6 1N106, 1 ≤ M ≤ 2 × 1 0 6 1≤M≤2×10^6 1M2×106

提示

由于數(shù)據(jù)量較大,請使用較為快速的輸入/輸出方式。

解題思路

根據(jù)數(shù)據(jù)范圍,我們估計算法的復(fù)雜度至多是 O ( N ) O(N) O(N),因此想到了動態(tài)規(guī)劃:

對于節(jié)點 i i i,有若干個節(jié)點與之相連,在與之相連的節(jié)點當(dāng)中從 1 1 1 k 1 , k 2 , . . . , k n k_1,k_2,...,k_n k1?,k2?,...,kn?節(jié)點的路徑長度相同且最短,那么我們計算得出,從 1 1 1到節(jié)點 i i i的最短路徑數(shù)為 n u m [ k 1 ] + n u m [ k 2 ] + . . . + n u m [ k n ] num[k_1]+num[k_2]+...+num[k_n] num[k1?]+num[k2?]+...+num[kn?]。

以上是思路的主體部分,接下來實現(xiàn)代碼:

數(shù)據(jù)量龐大,同時也是因為存在重邊,故不能采用二維數(shù)組存圖,因此采用鏈?zhǔn)角跋蛐恰?/p>

對于代碼主體部分,維護一個隊列與一個路徑長度的數(shù)組。

初始化將 1 1 1節(jié)點加入隊列,然后不斷嘗試到達新的節(jié)點。

void solve() {
	q.push(1);
	while (!q.empty()) {
		int node = q.front(); q.pop();
		
		for (int i = head[node]; i != -1; i = edges[i].next) {
			int v = edges[i].v;
			q.push(v);
		}
	}
}

利用隊列元素先進先出的特點,我們可以保證,隊首的節(jié)點永遠是距離 1 1 1最近的節(jié)點。

進而我們可以保證,用隊首去更新路徑長度,得到的一定是最短路徑長度。

void solve() {
	q.push(1);
	path[1] = 0;

	while (!q.empty()) {
		int node = q.front(); q.pop();
		int path_len = path[node] + 1;
		
		for (int i = head[node]; i != -1; i = edges[i].next) {
			int v = edges[i].v;
			if (path_len > path[v]) continue;
			if (path[v] == NaN) {//NaN代表無窮大,即為未到達的節(jié)點
				path[v] = path_len;
				q.push(v);
			}
		}
	}
}

以此為基礎(chǔ),很容易實現(xiàn)最初的思想:

void solve() {
	q.push(1);
	path[1] = 0;
	sum[1] = 1LL;

	while (!q.empty()) {
		int node = q.front(); q.pop();

		int path_len = path[node] + 1;
		
		for (int i = head[node]; i != -1; i = edges[i].next) {
			int v = edges[i].v;
			if (path_len > path[v]) continue;
			sum[v] = (sum[v] + sum[node]) % mod_num;
			if (path[v] == NaN) {
				path[v] = path_len;
				q.push(v);
			}
		}
	}
}

最后,AC代碼如下:文章來源地址http://www.zghlxwxcb.cn/news/detail-421576.html

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <queue>
#include <string.h>
using namespace std;
const int max_n = 1e6;
const int max_m = 2e6;
const int NaN = 0x3F3F3F3F;
const long long mod_num = 100003;

struct edge { int v, next; }edges[2 * max_m];
int tot = -1, head[max_n + 1], path[max_n + 1];
queue<int>q;
long long sum[max_n + 1];

void add_edge(int u, int v) {
	edges[++tot] = { v, head[u] }; head[u] = tot;
	edges[++tot] = { u, head[v] }; head[v] = tot;
}

void solve() {
	q.push(1);
	path[1] = 0;
	sum[1] = 1LL;

	while (!q.empty()) {
		int node = q.front(); q.pop();

		int path_len = path[node] + 1;
		
		for (int i = head[node]; i != -1; i = edges[i].next) {
			int v = edges[i].v;
			if (path_len > path[v]) continue;
			sum[v] = (sum[v] + sum[node]) % mod_num;
			if (path[v] == NaN) {
				path[v] = path_len;
				q.push(v);
			}
		}
	}
}

int main() {
	memset(head, -1, sizeof(int) * (max_n + 1));
	memset(path, 0x3F, sizeof(int) * (max_n + 1));
	int n, m;
	scanf("%d%d", &n, &m);
	//cin >> n >> m;
	int u, v;
	for (int i = 0; i < m; i++) {
		scanf("%d%d", &u, &v);
		//cin >> u >> v;
		add_edge(u, v);
	}

	solve();
	for (int i = 1; i <= n; i++) {
		printf("%lld\n", sum[i]);
	}
	return 0;
}

到了這里,關(guān)于[Daimayuan] 最短路計數(shù)(C++,DP,圖論)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 【C++ 實現(xiàn)】圖論概念,最小生成樹,單/多源最短路徑實現(xiàn)

    【C++ 實現(xiàn)】圖論概念,最小生成樹,單/多源最短路徑實現(xiàn)

    首先節(jié)點的存取,V是節(jié)點key,vectorpairV,V map;其實已經(jīng)能表達一個圖了,但是這樣保存節(jié)點對我們使用來說會導(dǎo)致復(fù)雜度高。 常用保存節(jié)點的方式,有矩陣和鄰接表。 矩陣的優(yōu)點:O(1) 時間找到兩點是否相連以及他們的權(quán)值。 矩陣的缺點:找一點相鄰的所有節(jié)點的時候是O(N

    2024年02月13日
    瀏覽(21)
  • [Daimayuan] 吃糖果(C++,貪心)

    桌子上從左到右放著 n n n 個糖果。糖果從左到右編號,第 i i i 塊糖果的重量為 w i w_i w i ? 。小明和小紅要吃糖果。 小明從左邊開始吃任意數(shù)量的糖果。(連續(xù)吃,不能跳過糖果) 小紅從右邊開始吃任意數(shù)量的糖果。(連續(xù)吃,不能跳過糖果) 當(dāng)然,如果小明吃了某個糖果

    2024年02月02日
    瀏覽(24)
  • [Daimayuan] 碰撞2(C++,模擬)

    [Daimayuan] 碰撞2(C++,模擬)

    在 x O y xOy x O y 坐標(biāo)系中有 N N N 個人,第 i i i 個人的位置是 ( X i , Y i ) (X_i,Y_i) ( X i ? , Y i ? ) ,并且每個人的位置都不同。 我們有一個由 L 和 R 組成的長為 N N N 的字符串 S S S , S i = S_i= S i ? = R 代表第 i i i 個人面向右, S i = S_i= S i ? = L 代表第 i i i 個人面向左。 現(xiàn)在所

    2023年04月09日
    瀏覽(24)
  • [Daimayuan] 添加括號(C++,數(shù)學(xué))

    現(xiàn)在給出一個表達式,形如 a 1 / a 2 / a 3 / . . . / a n a_1/a_2/a_3/.../a_n a 1 ? / a 2 ? / a 3 ? /.../ a n ? 。 如果直接計算,就是一個個除過去,比如 1 / 2 / 1 / 4 = 1 / 8 1/2/1/4=1/8 1/2/1/4 = 1/8 。 然而小 A A A 看到一個分?jǐn)?shù)感覺很不舒服,希望通過添加一些括號使其變成一個整數(shù)。一種可行

    2024年02月05日
    瀏覽(21)
  • [Daimayuan]新國王游戲(C++,數(shù)學(xué))

    又到了 H H H 國國慶, 國王再次邀請 n n n 位大臣來玩有獎游戲。上次國慶被眾臣吐槽國王小氣后,國王決定今年大方點,改變游戲規(guī)則且不再參與游戲,免得被大臣們質(zhì)疑。首先, 他讓每位大臣在左、 右手上面分別寫下一個正整數(shù)。然后讓這 n n n 位大臣排成一排。排好隊后,

    2023年04月08日
    瀏覽(18)
  • [Daimayuan] 異或和(C++,異或,數(shù)學(xué))

    給定一個長度為 n n n 的數(shù)組 a 1 , a 2 , . . . , a n a_1,a_2,...,a_n a 1 ? , a 2 ? , ... , a n ? 。 請你求出下面式子的模 1 e 9 + 7 1e9+7 1 e 9 + 7 的值。 ∑ i = 1 n ? 1 ∑ j = i + 1 n ( a i ? X O R ? a j ) sum_{i=1}^{n-1}{sum_{j=i+1}^{n}{(a_i XOR a_j)}} ∑ i = 1 n ? 1 ? ∑ j = i + 1 n ? ( a i ? ? XOR ? a j ?

    2024年02月01日
    瀏覽(91)
  • [Daimayuan] 三段式(C++,數(shù)組前綴和)

    有一個長度為 n n n 的序列,現(xiàn)在我們想把它切割成三段(每一段都是連續(xù)的),使得每一段的元素總和都相同,請問有多少種不同的切割方法 輸入描述 第一行給出一個數(shù) n n n ,( 1 ≤ n ≤ 1 0 5 1≤n≤10^5 1 ≤ n ≤ 1 0 5 ) 第二行給出序列 a 1 a_1 a 1 ? , a 2 a_2 a 2 ? , a 3 a_3 a 3 ?

    2024年02月05日
    瀏覽(18)
  • P1144 最短路計數(shù)

    給出一個 N N N 個頂點 M M M 條邊的無向無權(quán)圖,頂點編號為 1 ~ N 1sim N 1 ~ N 。問從頂點 1 1 1 開始,到其他每個點的最短路有幾條。 第一行包含 2 2 2 個正整數(shù) N , M N,M N , M ,為圖的頂點數(shù)與邊數(shù)。 接下來 M M M 行,每行 2 2 2 個正整數(shù) x , y x,y x , y ,表示有一條由頂點 x x x 連

    2024年02月14日
    瀏覽(19)
  • P1144 最短路計數(shù) 題解

    給出一個 N N N 個頂點 M M M 條邊的無向無權(quán)圖,頂點編號為 1 ~ N 1sim N 1 ~ N 。問從頂點 1 1 1 開始,到其他每個點的最短路有幾條。 第一行包含 2 2 2 個正整數(shù) N , M N,M N , M ,為圖的頂點數(shù)與邊數(shù)。 接下來 M M M 行,每行 2 2 2 個正整數(shù) x , y x,y x , y ,表示有一條由頂點 x x x 連

    2024年02月05日
    瀏覽(16)
  • 算法:計數(shù)類dp

    算法:計數(shù)類dp

    ??計數(shù)類動態(tài)規(guī)劃(Counting DP)是一種用來解決計數(shù)問題的動態(tài)規(guī)劃技術(shù),它通常用于求解在給定條件下滿足某種性質(zhì)的組合或序列的總數(shù)。 計數(shù)類DP問題的特點是要求計算所有可能情況的數(shù)量,而不是求最值或是否存在這樣的情況。 當(dāng)然我們在使用計數(shù)類dp的時候,沒必

    2024年04月15日
    瀏覽(14)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包