「LOJ #10064」 黑暗城堡
作者:互联网
知道黑暗城堡有 \(N\) 个房间,\(M\) 条可以制造的双向通道,以及每条通道的长度。
城堡是树形的并且满足下面的条件:
设 \(D_i\) 为如果所有的通道都被修建,第 \(i\) 号房间与第 \(1\) 号房间的最短路径长度;
而 \(S_i\) 为实际修建的树形城堡中第 \(i\) 号房间与第 \(1\) 号房间的路径长度;
要求对于所有整数 \(i(1≤i≤N)\),有 \(S_i=D_i\) 成立。
你想知道有多少种不同的城堡修建方案。当然,你只需要输出答案对 \(2^{31}−1\) 取模之后的结果就行了。
分析
第一步肯定求出 \(1\) 号节点到每个点的最短路,然后考虑建路。
因为要保证建好的路必须使该节点到 \(1\) 号节点的实际路径长度等于最短路长度,所以我们枚举每个点 \(u\) ,与 \(u\) 相连的边集为 \(T\) ,找到 \(edge(u,v)\in T\) ,使得 \(dis[v]=dis[u]+w(u,v)\) 就好了。
找 \(v\) 点的话,在 \(Dijkstra\) 中直接计数就行了。
注意: \(M\) 一定要设为 \(N*N\) 而不是 \(N*N/2\) !!!用 C++(NOI) 编译会显示超时,这可把我坑惨了......
代码
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 1003
#define M N*N
#define il inline
#define re register
#define INF 0x3f3f3f3f
#define tie0 cin.tie(0),cout.tie(0)
#define fastio ios::sync_with_stdio(false)
#define File(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout)
using namespace std;
typedef long long ll;
template <typename T> inline void read(T &x) {
T f = 1; x = 0; char c;
for (c = getchar(); !isdigit(c); c = getchar()) if (c == '-') f = -1;
for ( ; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + (c ^ 48);
x *= f;
}
const ll mod = (1ll << 31) - 1ll;
struct edge {
int to, nxt, v;
} e[M];
int n, m;
ll ret = 1;
int head[M], cnt;
int d[N], ans[N];
bool vis[N];
void insert(int u, int v, int w) {
e[++cnt].to = v, e[cnt].nxt = head[u], e[cnt].v = w, head[u] = cnt;
}
void Dijkstra() {
for (int i = 2; i <= n; ++i) d[i] = INF;
priority_queue < pair<int, int> > q;
q.push(make_pair(0, 1));
while (!q.empty()) {
int u = q.top().second; q.pop();
if (vis[u]) continue;
vis[u] = 1;
for (int i = head[u]; i; i = e[i].nxt) {
int v = e[i].to, w = e[i].v;
if (d[u] + w < d[v]) {
d[v] = d[u] + w; ans[v] = 1;
q.push(make_pair(-d[v], v));
}
else if (d[u] + w == d[v]) ans[v]++;
}
}
}
int main() {
int u, v, w;
read(n), read(m);
for (int i = 1; i <= m; ++i) {
read(u), read(v), read(w);
insert(u, v, w), insert(v, u, w);
}
Dijkstra();
for (int i = 1; i <= n; ++i)
if (ans[i])
ret = ret * ans[i] % mod;
printf("%lld", ret);
return 0;
}
标签:10064,LOJ,城堡,int,read,长度,include,define 来源: https://www.cnblogs.com/hlw1/p/12260565.html