黑暗城堡

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

以上是关于黑暗城堡的主要内容,如果未能解决你的问题,请参考以下文章

一本通 3.1 例 1」黑暗城堡

黑暗城堡

黑暗城堡

黑暗城堡-(最小生成树+最短路)

T57274 黑暗城堡

CH6202 黑暗城堡