CH6202 黑暗城堡
Posted iowa-battleship
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CH6202 黑暗城堡相关的知识,希望对你有一定的参考价值。
一道最短路+生成树
原题链接
实际上就是生成树的中每个点到节点(1)的距离等于原图中这个点到节点(1)的最短距离,求这样的生成树的棵数。
先用(SPFA)或(Dijkstra)求出所有点到节点(1)的最短路径(dis[x]),然后将所有节点按(dis)从小到大排序。
枚举(x),表示已经有(x-1)个点添入树,现在要添加第(x)个点。
统计有多少个点(y)满足(y)是已添入树的点,且(dis[y]+edge(x,y)=dis[x]),(edge)表示边长。
最后将每次将某个点添入树时的方案数累乘起来即可。
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 1010;
const int mod = 1LL * (1 << 31) - 1;
struct dd {
int x, D;
};
dd dis[N];
int a[N][N];
bool v[N];
int re()
{
int x = 0;
char c = getchar();
bool p = 0;
for (; c<'0' || c>'9'; c = getchar())
p |= c == '-';
for (; c >= '0'&&c <= '9'; c = getchar())
x = x * 10 + (c - '0');
return p ? -x : x;
}
int comp(dd x, dd y)
{
return x.D < y.D;
}
inline int minn(int x, int y)
{
return x < y ? x : y;
}
int main()
{
int i, j, n, m, x, y, s = 1, k;
n = re();
m = re();
memset(a, 60, sizeof(a));
memset(dis, 60, sizeof(dis));
for (i = 1; i <= n; i++)
{
a[i][i] = 0;
dis[i].x = i;
}
for (i = 1; i <= m; i++)
{
x = re();
y = re();
a[x][y] = a[y][x] = re();
}
dis[1].D = 0;
for (i = 1; i <= n; i++)
{
x = 0;
for (j = 1; j <= n; j++)
if (!v[j] && (dis[j].D < dis[x].D || !x))
x = j;
if (!x)
break;
v[x] = 1;
for (j = 1; j <= n; j++)
dis[j].D = minn(dis[j].D, dis[x].D + a[x][j]);
}
sort(dis + 1, dis + n + 1, comp);
for (i = 2; i <= n; i++)
{
k = 0;
for (j = 1; j < i; j++)
if (dis[j].D + a[dis[j].x][dis[i].x] == dis[i].D)
k++;
s = (1LL * s*k) % mod;
}
printf("%d", s);
return 0;
}
ps:因为我用的是(VS),所以代码会自动补空格,而我本来的风格是没有空格的。
以上是关于CH6202 黑暗城堡的主要内容,如果未能解决你的问题,请参考以下文章