黑暗城堡

黑暗城堡

时间限制: 1 Sec  内存限制: 128 MB

题目描述

你知道黑暗城堡有N个房间(1≤N≤1000),M条可以制造的双向通道,以及每条通道的长度。
城堡是树形的并且满足下面的条件:如果所有的通道都被修建,设D[i]为第i号房间与第1号房间的最短路径长度;而S[i]为实际修建的树形城堡中第i号房间与第1号房间的路径长度;要求对于所有整数i(1≤i≤N),有S[i]=D[i]成立。
你想知道有多少种不同的城堡修建方案。当然,你只需要输出答案对231-1取模之后的结果就行了。

样例输入

4 6
1 2 1
1 3 2
1 4 3
2 3 1
2 4 2
3 4 1

样例输出

6

最短路径树SPT(Short Path Tree)是网络的源点到所有结点的最短路径构成的树。那么本题就是相求有多少颗以1为源点的最短路径树。那么可以先求出每个点的入边中,有多少条是最短路径上的边,再考虑按照最短路径大小升序依次访问这些点,当我们访问到某种状态时,需要拓展下一个点,那么这个点的入边在最短路径上的边都可以成为我们拓展的边,于是答案乘上这个边数。
#include<bits/stdc++.h>
using namespace std;
const int N =1005;
const long long mod=(1ll<<31) - 1;
 
struct ss
{
    int u,v,w,next;
};
ss edg[N*N];
int head[N],sum_edge=0;
 
void addedge(int u,int v,int w)
{
    edg[sum_edge]=(ss){u,v,w,head[u]};
    head[u]=sum_edge++;
}
 
priority_queue<pair<long long,int> >q;
int vis[N]={0};
long long dis[N];
 
void dij(int S)
{
    for(int i=0;i<N;i++)dis[i]=LLONG_MAX/2;
    dis[S]=0;
    q.push(make_pair(0,S));
 
    while(q.size())
    {
        int x=q.top().second;
        q.pop();
 
        if(vis[x])continue;
        vis[x]=1;
 
        for(int i=head[x];i!=-1;i=edg[i].next)
        {
            int v=edg[i].v;
            if(dis[v]>dis[x]+edg[i].w)
            {
                dis[v]=dis[x]+edg[i].w;
                q.push(make_pair(-dis[v],v));
            }
        }
    }
}
 
int main()
{
    memset(head,-1,sizeof(head));
    int n,m;
    scanf("%d %d",&n,&m);
    while(m--)
    {
        int u,v,w;
        scanf("%d %d %d",&u,&v,&w);
        addedge(u,v,w);
        addedge(v,u,w);
    }
 
    dij(1);
 
 
 
    long long ans=1;
    long long cnt[N]={0};
    pair<long long ,int >arr[N];
    for(int i=1;i<=n;i++)
    {
        arr[i].first=dis[i];
        arr[i].second=i;
    }
 
    sort(arr+1,arr+1+n);
 
    for(int i=1;i<=n;i++)
    {
        int x=arr[i].second;
 
        for(int j=head[x];j!=-1;j=edg[j].next)
        {
            int v=edg[j].v;
            if(dis[v]==dis[x]+edg[j].w)cnt[v]++;
        }
        ans*=max(cnt[x],1ll);
        ans%=mod;
    }
 
    printf("%lld
",ans);
    return 0;
 
 
}
View Code
原文地址:https://www.cnblogs.com/tian-luo/p/11262654.html