黑暗城堡

黑暗城堡

题意

给出一张 n 个点 m 条边的图,求该图有多少棵生成树满足生成树上每个点 x1 的最短距离 Sx 等于原图 x1 的最短距离 Dx,答案 mod2311

思路

先考虑如何求出一棵满足条件的生成树。

1 为这棵生成树的根,容易发现对于 x 的儿子 y,记 dx1x 的距离,(x,y)xy 的距离,有 dy=dx+(x,y)

先以 1 为源点求一遍单源最短路,再从 1 开始遍历整张图,每次选出合法的后继点作为自己的儿子。

再考虑如何求出所有符合条件的生成树。

我们先随意求出一棵合法生成树,再在这棵生成树上计数。

fx 为以 x 为根的子树可以变为多少种合法树,cxx 有多少个合法的爹,即满足 dx=dy+c(x,y)y 的个数,有:

fx=ysonxfy×cy

即每个儿子可以随意换爸爸,每个儿子相互独立,乘起来就行。

答案为 f1,时间复杂度:O(n2)

代码

#include <bits/stdc++.h>
using namespace std;

using LL = long long;
const int N = 1e6 + 5;
const LL mod = (1ll << 31) - 1;

int tot, head[N], nxt[N << 1];
int ver[N << 1], edge[N << 1];
int n, m, dis[N];
bool vis[N];
LL f[N];

void add(int u, int v, int w) {
	ver[++ tot] = v;
	nxt[tot] = head[u];
	head[u] = tot;
	edge[tot] = w;
}

struct node {
	int d, id;
};
bool operator < (node x, node y) {
	return x.d > y.d;
}

void dijkstra() {
	memset(dis, 0x3f, sizeof(dis));
	memset(vis, 0, sizeof(vis));
	dis[1] = 0;
	priority_queue <node> Q;
	Q.push({0, 1});
	while (!Q.empty()) {
		int x = Q.top().id; Q.pop();
		if (vis[x]) continue;
		vis[x] = 1;
		for (int i = head[x]; i; i = nxt[i]) {
			int y = ver[i], z = edge[i];
			if (dis[y] > dis[x] + z) {
				dis[y] = dis[x] + z;
				Q.push({dis[y], y}); 
			}
		}
	}
	memset(vis, 0, sizeof(vis));	
}

void dfs(int x) {
	vis[x] = 1, f[x] = 1;	
	for (int i = head[x]; i; i = nxt[i]) {
		int y = ver[i], z = edge[i];
		if (vis[y]) continue;
		if (dis[y] != dis[x] + z) continue;
		dfs(y); 
		LL cnt = 0;
		for (int j = head[y]; j; j = nxt[j]) 
			if (dis[ver[j]] + edge[j] == dis[y]) 
				cnt ++;
		f[x] *= f[y] * cnt % mod;
		f[x] %= mod;
	}
}

int main() {
	freopen("dark.in", "r", stdin);
	freopen("dark.out", "w", stdout);
	
	cin >> n >> m;
	for (int i = 1; i <= m; i ++) {
		int u, v, w;
		cin >> u >> v >> w;
		add(u, v, w);
		add(v, u, w);
	}
	
	dijkstra();
	dfs(1);
	
	cout << f[1] << "\n";
	return 0;
}
posted @   maniubi  阅读(3)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示