黑暗城堡
Posted fangbozhen
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了黑暗城堡相关的知识,希望对你有一定的参考价值。
ttps://loj.ac/problem/10064
题目描述
??给出一张图,求它最短路径树的个数。
思路
??最短路径树就是对于根节点(u),它到任意(v)的最小距离等于树上的距离。我们考虑(dijkstra)的过程,每一次选择一个与起始节点距离最小的点加入已确定的集合,所以我们每次选择的边组成的集合就是一种最短路径树。至于统计方案,在进行(dijkstra)的时候,我们可以判断每一条边,如果(dis[v]=dis[u]+e[i])方案数可以累乘,不过如果更新(dis)需要重置到这一点的最短路方案数。当然我们也可以在跑完(dijkstra)后统计答案。
代码
#include <bits/stdc++.h>
using namespace std;
const long long mod=2147483647;
const int MAXN=1005,MAXM=5e5+10;
int head[MAXN],nxt[MAXM*2],to[MAXM*2],w[MAXM*2],tot;
int dis[MAXN];
bool vis[MAXN];
void add_edge(int x,int y,int z)
{
nxt[++tot]=head[x];
head[x]=tot;
to[tot]=y;
w[tot]=z;
}
priority_queue<pair<int,int> >q;
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
add_edge(x,y,z);
add_edge(y,x,z);
}
memset(dis,0x3f,sizeof(dis));
dis[1]=0;
q.push(make_pair(0,1));
while(!q.empty())
{
int x=q.top().second;q.pop();
if(vis[x])continue ;
vis[x]=1;
for(int i=head[x];i;i=nxt[i])
{
int y=to[i],v=w[i];
if(dis[y]>dis[x]+v)
{
dis[y]=dis[x]+v;
q.push(make_pair(-dis[y],y));
}
}
}
/* for(int i=1;i<=n;i++)
printf("%d ",dis[i]);
printf("
");*/
long long ans=1;
for(int i=1;i<=n;i++)
{
long long s=0;
for(int j=head[i];j;j=nxt[j])
{
int k=to[j],v=w[j];
if(dis[i]==dis[k]+v)
s++;
}
// cout<<s<<' '<<ans<<endl;
if(s!=0)ans=(ans*s)%mod;
}
printf("%lld
",ans);
return 0;
}
以上是关于黑暗城堡的主要内容,如果未能解决你的问题,请参考以下文章