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

    #10064. 「一本通 3.1 例 1」黑暗城堡

    内存限制:512 MiB 时间限制:1000 ms 标准输入输出
    题目类型:传统    评测方式:文本比较
    上传者: 1bentong
    提交    提交记录    统计    讨论    测试数据
     

    题目描述

    你知道黑暗城堡有 N 个房间,M 条可以制造的双向通道,以及每条通道的长度。

    城堡是树形的并且满足下面的条件:

    设 Di 为如果所有的通道都被修建,第 i 号房间与第 1 号房间的最短路径长度;

    而 Si​​ 为实际修建的树形城堡中第 i 号房间与第 1 号房间的路径长度;

    要求对于所有整数 i (1iN),有 Si=Di​​ 成立。

    你想知道有多少种不同的城堡修建方案。当然,你只需要输出答案对 2^31 取模之后的结果就行了。

    输入格式

    第一行为两个由空格隔开的整数 N,M;

    第二行到第 M+1 行为 3 个由空格隔开的整数 x,y,l:表示 号房间与 y 号房间之间的通道长度为 l

    输出格式

    一个整数:不同的城堡修建方案数对 2^31 取模之后的结果。

    样例

    样例输入

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

    样例输出

    6

    样例说明

    一共有 4 个房间,6 条道路,其中 1 号和 2 号,1 号和 3 号,1 号和 4 号,2 号和 3 号,2 号和 4 号,3 号和 4 号房间之间的通道长度分别为 1,2,3,1,2,1。

    而不同的城堡修建方案数对 2^31 取模之后的结果为 6

    数据范围与提示

    对于全部数据,1≤N≤10001≤M≤N(N−1)/21≤l≤200

    题意:

    求一个无向图中最短路径树的棵数。

    最短路径树的定义:

    选出$N-1$条边组成一棵树,对于给定的源点$S$,

    若任何点$u$均满足在原图上$S$到点$u$的最短路$dis(u)$等于在这棵树上$S$到$u$的最短路$disnew(u)$,

    则这棵树是一棵最短路径树。

    猜了个结论,然后写了。错了。发现输入写错了。

    (千万不要把连边读入写成$add(read(),read(),read())$,这玩意好像是反着读进来的)

    改了输入,$A$了。

    ……

    一个简单的性质:两棵有标号的树互不相同当且仅当存在一个点u在两棵树中的$fa(u)$不同。

    考虑生成一棵最短路径树的方法,只需要在$dis(v)>dis(u)+e(u,v)$(即发生更新)时记录$fa(v)=u$,

    最后按父子关系把树连起来即可。由于每个点都有且仅有一个$fa$,可以证明这一定是一棵树。

    我们发现,若出现一个$v$使得$dis(v)=dis(u)+e(u,v)$,$fa(v)$便有两种选择,任取一种均合法。

    推广开来,当出现$N$个$dis(v)=dis(u)+e(u,v)$时,$fa(v)$便有$N+1$种选择,任取一种均合法。

    (由于$dis(v)=dis(u)+e(u,v)$这样的状态不会影响最短路算法的运行,所以$fa(v)$取何值都不会对其他点产生影响)

    既然每个点互不影响,我们就可以直接运用乘法原理把每个$fa(v)$的选择数乘起来得到答案。

    显然$fa(v)$的选择数就是满足$dis(v)=dis(u)+e(u,v)$的u的数目(这不是S到v的最短路径数),打板即可。

    代码:

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<queue>
    
    using namespace std;
    #define MAXN 100005
    #define MAXM 1000005
    #define mod 0x7fffffff
    #define ll long long
    
    ll hd[MAXN],to[MAXM<<1],cnt;
    ll nxt[MAXM<<1],cst[MAXM<<1];
    struct node{
        ll u,w;
        bool operator<(const node b)const
            {return w>b.w;}
    };
    ll dis[MAXN],ans[MAXN];
    bool vis[MAXN];
    inline ll read(){
        ll x=0,f=1;
        char c=getchar();
        for(;!isdigit(c);c=getchar())
            if(c=='-')
                f=-1;
        for(;isdigit(c);c=getchar())
            x=x*10+c-'0';
        return x*f;
    }
    
    inline void addedge(ll u,ll v,ll w){
        to[++cnt]=v,cst[cnt]=w,nxt[cnt]=hd[u],hd[u]=cnt;
        to[++cnt]=u,cst[cnt]=w,nxt[cnt]=hd[v],hd[v]=cnt;
        return;
    }
    
    inline void Dijkstra(ll s){
        memset(dis,127,sizeof(dis));
        priority_queue<node> q;
        q.push((node){s,0}); 
        ans[1]=1;dis[s]=0;
        while(!q.empty()){
            node tp=q.top();q.pop();
            if(vis[tp.u]) continue;
            vis[tp.u]=1;
            for(ll i=hd[tp.u];i;i=nxt[i]){
                ll v=to[i],w=cst[i];
                if(dis[v]>tp.w+w){
                    ans[v]=1,dis[v]=tp.w+w;
                    q.push((node){v,dis[v]});
                }
                else if(dis[v]==tp.w+w) ans[v]++;
            }
        }
        return;    
    }
    
    int main(){
        ll N=read(),M=read(),num=1;
        for(ll i=1;i<=M;i++){
            ll u=read(),v=read(),w=read();
            addedge(u,v,w);
        }
        Dijkstra(1);
        for(ll i=1;i<=N;i++) num*=ans[i]%mod,num%=mod;
        printf("%lld
    ",num%mod);
        return 0;
    }
  • 相关阅读:
    Microsoft Enterprise Library 5.0 系列(二) Cryptography Application Block (初级)
    Microsoft Enterprise Library 5.0 系列(五) Data Access Application Block
    Microsoft Enterprise Library 5.0 系列(八) Unity Dependency Injection and Interception
    Microsoft Enterprise Library 5.0 系列(九) Policy Injection Application Block
    Microsoft Enterprise Library 5.0 系列(三) Validation Application Block (高级)
    软件研发打油诗祝大家节日快乐
    从挖井的故事中想到开发管理中最容易忽视的几个简单道理
    ITIL管理思想的执行工具发布
    管理类软件设计“渔”之演化
    20070926日下午工作流与ITILQQ群 事件管理 讨论聊天记录
  • 原文地址:https://www.cnblogs.com/YSFAC/p/9851837.html
Copyright © 2011-2022 走看看