zoukankan      html  css  js  c++  java
  • 黑暗城堡

    黑暗城堡

    时间限制: 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
  • 相关阅读:
    反编译Silverlight项目
    李开复关于创新的五条建议
    Android人脸检测类FaceDetector
    吃火锅如何进行口腔保健
    ListView优化
    番茄工作法
    App Inventor for Android初接触
    QPainter如何自适应大小画图
    Eclipsejava.lang.OutOfMemoryError: PermGen space
    健康小工具——体脂肪率自测
  • 原文地址:https://www.cnblogs.com/tian-luo/p/11262654.html
Copyright © 2011-2022 走看看