• 黑暗城堡


    描述

    在顺利攻破Lord lsp的防线之后,lqr一行人来到了Lord lsp的城堡下方。Lord lsp黑化之后虽然拥有了强大的超能力,能够用意念力制造建筑物,但是智商水平却没怎么增加。现在lqr已经搞清楚黑暗城堡有N个房间 (1≤N≤1000),M条可以制造的双向通道,以及每条通道的长度。
    lqr深知Lord lsp的想法,为了避免每次都要琢磨两个房间之间的最短路径,Lord lsp一定会把城堡修建成树形的;但是,为了尽量提高自己的移动效率,Lord lsp一定会使得城堡满足下面的条件:设 D[i] 为如果所有的通道都被修建,第 i 号房间与第1号房间的最短路径长度;而 S[i] 为实际修建的树形城堡中第 i 号房间与第1号房间的路径长度;要求对于所有整数 i(1≤i≤N),有 S[i]=D[i] 成立。
    为了打败Lord lsp,lqr想知道有多少种不同的城堡修建方案。于是lqr向applepi提出了这个问题。因为applepi还要忙着出模拟赛,所以这个任务就交给你了。当然,你只需要输出答案对 2^31–1 取模之后的结果就行了。

    输入

    第一行有两个整数N 和M。
    之后M 行,每行三个整数X,Y 和L,表示可以修建X 和Y 之间的一条长度为L 的通道。

    输出

    一个整数,表示答案对 2^31–1 取模之后的结果。

    样例输入

    3 3
    1 2 2
    1 3 1
    2 3 1

    样例输出

    2

    解题思路:dij找出在最短路径上的边。统计出能构成最短路径树时每个点经过几次,相乘就是答案。

    #include <bits/stdc++.h>
    #define pii pair<int,int>
    #define LL __int64 
    #define INF 0x3f3f3f3f
    using namespace std;
    const int N=1e3+5;
    vector<pii>G[N];
    int M[N][N];
    int n,m;
    const LL mod=pow(2,31)-1;
    struct node
    {
        int id;
        LL d;
    }dis[N];
    void dij()
    {
        for(int i=1;i<=n;i++) dis[i].d=INF,dis[i].id=i;
        dis[1].d=0;
        queue<int>qu;
        qu.push(1);
        while(!qu.empty()){
            int u=qu.front();qu.pop();
            for(int i=0;i<G[u].size();i++){
                int v=G[u][i].first,c=G[u][i].second;
                if(dis[v].d>dis[u].d+c){
                    dis[v].d=dis[u].d+c;
                    qu.push(v);
                }
            }
        }
    }
    bool cmp(node a,node b)
    {
        if(a.d!=b.d) return a.d<b.d;
        return a.id<b.id;
    }
    int main()
    {
        int k;
        ios::sync_with_stdio(false);
        cin>>n>>m;    
        memset(M,INF,sizeof(M));
        for(int i=1,u,v,c;i<=m;i++){
            cin>>u>>v>>c;
            M[u][v]=M[v][u]=min(M[u][v],c);
            G[u].push_back(pii(v,c));
            G[v].push_back(pii(u,c));
        }
        dij(); 
        LL sum=1;
        sort(dis+1,dis+1+n,cmp);
        for(int i=2;i<=n;i++){
            LL cnt=0;
            for(int j=1;j<i;j++){
                int u=dis[j].id,v=dis[i].id;
                //cout<<u<<" "<<v<<endl;
                if(dis[j].d+M[u][v]==dis[i].d) cnt++;
            }
            sum=sum*cnt%mod;
        }
        cout<<sum<<endl;
    } 
  • 相关阅读:
    C++ 指针 new delete int*与string
    61.Android适配的那些P事(转)
    60.Android通用流行框架大全
    Android Studio配置指南总结
    大数据学习资源(下)
    大数据学习资源(上)
    59.Android开源项目及库 (转)
    Linux 简介
    7款应用最广泛的Linux桌面环境盘点
    58. Android一些开发习惯总结
  • 原文地址:https://www.cnblogs.com/ww123/p/11648734.html
Copyright © 2020-2023  润新知