黑暗城堡
黑暗城堡
题意
给出一张
思路
先考虑如何求出一棵满足条件的生成树。
令
先以
再考虑如何求出所有符合条件的生成树。
我们先随意求出一棵合法生成树,再在这棵生成树上计数。
记
即每个儿子可以随意换爸爸,每个儿子相互独立,乘起来就行。
答案为
代码
#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;
}
本文来自博客园,作者:maniubi,转载请注明原文链接:https://www.cnblogs.com/maniubi/p/18470997,orz
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】