首页 > 其他分享 >黑暗城堡

黑暗城堡

时间:2024-10-16 21:44:43浏览次数:4  
标签:黑暗 int 城堡 生成 vis continue mod dis

黑暗城堡

题意

给出一张 \(n\) 个点 \(m\) 条边的图,求该图有多少棵生成树满足生成树上每个点 \(x\) 到 \(1\) 的最短距离 \(S_x\) 等于原图 \(x\) 到 \(1\) 的最短距离 \(D_x\),答案 \(\bmod 2^{31}-1\)。

思路

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

令 \(1\) 为这棵生成树的根,容易发现对于 \(x\) 的儿子 \(y\),记 \(d_x\) 为 \(1\) 到 \(x\) 的距离,\((x,y)\) 为 \(x\) 到 \(y\) 的距离,有 \(d_y=d_x+(x,y)\)。

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

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

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

记 \(f_x\) 为以 \(x\) 为根的子树可以变为多少种合法树,\(c_x\) 为 \(x\) 有多少个合法的爹,即满足 \(d_x=d_y+c(x,y)\) 的 \(y\) 的个数,有:

\[f_x=\prod_{y \in son_x} f_y \times c_y \]

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

答案为 \(f_1\),时间复杂度:\(O(n^2)\)。

代码

#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;
}

标签:黑暗,int,城堡,生成,vis,continue,mod,dis
From: https://www.cnblogs.com/maniubi/p/18470997

相关文章

  • #C. 黑暗城堡
    #C.黑暗城堡题意设D[i]为第i号房间与第1号房间的最短路径长度;S[i]为实际修建的树形城堡中第i号房间与第1号房间的路径长度要求对于所有整数i(1<=i<=N),有S[i]=D[i]成立的方案数分析跑一遍最短路,再\(N^2\)暴力每两个点之间的边如果\(dis(1,j)=dis(1......
  • 树上差分+lca 黑暗的锁链
    //**太久不写了,感觉很难受。。。比赛最近打得也不好,课内任务又重,还要忙着做项目。何去何从。今天又写了一题,用了树上差分的知识。下面来整理整理。1.首先让我们学一下lca(最小公共父节点) 我用的是倍增来求的。总共其实就是两步:dfs打ST表预处理每个点的上面节点 lca求两......
  • 黑暗之魂 I&#038;II 合集,豪华中文,重制最终版-灭绝深渊-原罪学者+全DLC+修改器,解压即
    游戏截图《黑暗之魂I&II合集》是一款由FromSoftware开发的经典动作角色扮演游戏合集,囊括了《黑暗之魂》系列的前两部作品:《黑暗之魂:重制版》和《黑暗之魂II:原罪学者》。该合集为玩家提供了进入深邃而神秘的黑暗奇幻世界的机会,体验系列标志性的高难度战斗和复杂的叙事设......
  • 植物在黑暗中的活动
    晚上温度低,降低植物的呼吸作用,会让更多的有机物保存下,导致植物的口感更丰富,比如更甜,更香。随着植物的生长,将植物的一部分填埋起来,会让植物的不见光部分更多的保留有机物,比如章丘大葱。植物在黑暗中进行一系列重要的生理活动,主要包括以下几个方面:呼吸作用:在光照下,植物通过......
  • 黑暗之魂2缺失steam_api.dll该如何处理?全面解读《黑暗之魂2》steam_api.dll丢失及高效
    在游戏的世界中,《黑暗之魂2》凭借其独特的魅力吸引了众多玩家。然而,有时玩家会遭遇steam_api.dll文件丢失的困扰,这无疑给游戏体验带来了极大的阻碍。在这篇文章中,我们将为您进行全面解读。首先深入剖析steam_api.dll文件丢失的原因。可能是由于游戏安装过程中的错误、系统更新......
  • Loj P10064 黑暗城堡 题解 最短路径树记数
    这道题是一道最短路径树问题。首先,什么是最短路径树呢?定义一个图的最短路径树表示一个图上的生成树,且根节点到图上任一点的距离等于原图上两者之间的距离。而不难发现,题目其实是在求图上最短路径树记数。首先,建出最短路径树。枚举每条边,判断边两个端点到根的距离之差是否为......
  • P1504 积木城堡/01背包板子
    代码:#define_CRT_SECURE_NO_WARNINGS#include<iostream>#include<vector>#include<algorithm>#include<math.h>#include<sstream>#include<string>#include<string.h>#include<iomanip>#include<stdlib.h>......
  • 《渣男代码历险记》第三章:天谴之子——光明与黑暗的对决
    “醒醒!醒醒!”“我这是在哪?”二。“你昏睡了34天了。”舅舅。“发生了什么?”舅舅哽咽了,半天说不出话来。“你。。。。。。是天谴之子。”“你为什么这样说?”“你只有放弃人类的未来,才能获得自身的幸福。现在全人类都被代码灭亡了。你答对一个计算机题目,就可以救若干个人类。......
  • 告别复制粘贴的黑暗时代!教你们一个新崛起的API
    在前端开发的世界里,复制粘贴功能就像是那个总是被忽视,却在关键时刻能救你一命的老朋友。我们习惯了用那些古老的魔法咒语(document.execCommand('copy'))来实现这一功能,但时代在进步,技术在更新,是时候告别那些让人头疼的兼容性问题,迎接新时代的剪贴板API了。旧时代的遗物在那个......
  • 黑暗城堡
    acwing链接原本以为是给我所有点到1号点的距离,然后问我有多少棵树满足这个要求。(一个明显是dp的dp吧)其实差不多,但是它已经把所有能选的边给你了。差别就是我枚举的时候多了一个要求。所以这题就是先跑一遍单源最短路,然后把所有点按照dist排序。以为没有负边,所以dist大的点一......