• 黑暗城堡(生成树)


    你知道黑暗城堡有 NN个房间,MM 条可以制造的双向通道,以及每条通道的长度。
    城堡是树形的并且满足下面的条件:
    设 Di为如果所有的通道都被修建,第 i 号房间与第 1 号房间的最短路径长度;
    而Si为实际修建的树形城堡中第 ii 号房间与第 11 号房间的路径长度;
    要求对于所有整数 i (1≤i≤N),有 Si=Di 成立。
    你想知道有多少种不同的城堡修建方案。当然,你只需要输出答案对 2^31−1取模之后的结果就行了。
    输入
    第一行为两个由空格隔开的整数 N,M;
    第二行到第 M+1行为 3个由空格隔开的整数x,y,l:表示 x 号房间与 yy号房间之间的通道长度为l.
    输出
    一个整数:不同的城堡修建方案数对 2^31−1取模之后的结果。
    样例输入
    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−1取模之后的结果为 6。
    对于全部数据,1≤N≤1000,1≤M≤N(N−1)2,1≤l≤2001≤N≤1000,1≤M≤N(N−1)2,1≤l≤200。

    本来好像是一道求最小生成树的个数的题

    结果被我用spfa给氧化钙过去了

    直接spfa求出点1到所有点的距离

    然后枚举每个点u以及其相邻的点v

    如果有dis[u]+val[e]==dis[v]dis[u]+val[e]==dis[v] (e为连接的边)

    那么说明能这一条边满足最后能构成最小生成树

    那么num[v]++

    因为乘法原理

    最后把所有num乘起来就是答案了

    #include<bits/stdc++.h>
    using namespace std;
    #define mod 2147483647
    inline int read(){
        char ch=getchar();
        int res=0;
        while(!isdigit(ch))ch=getchar();
        while(isdigit(ch)) res=(res<<3)+(res<<1)+(ch^48),ch=getchar();
        return res;
    }
    int n,m,adj[1004],nxt[1000005],to[1000005],cnt,val[1000005],dis[10005],num[10005];
    #define ll long long
    ll ans=1;
    bool vis[10005];
    inline void addedge(int u,int v,int w){
        nxt[++cnt]=adj[u],adj[u]=cnt,to[cnt]=v,val[cnt]=w;
        nxt[++cnt]=adj[v],adj[v]=cnt,to[cnt]=u,val[cnt]=w;
    }
    inline void spfa(){
        memset(dis,127,sizeof(dis));
        dis[1]=0;
        memset(vis,false,sizeof(vis));
        queue<int> q;
        q.push(1);
        while(!q.empty()){
            int u=q.front();
            q.pop(),vis[u]=false;
            for(int e=adj[u];e;e=nxt[e]){
                int v=to[e];
                if(dis[v]>dis[u]+val[e])
                {
                    dis[v]=dis[u]+val[e];
                    if(!vis[v]){
                        vis[v]=true;
                        q.push(v);
                    }
                }
            }
        }
    }
    int main(){
        n=read(),m=read();
        for(int i=1;i<=m;i++){
            int u=read(),v=read(),w=read();
            addedge(u,v,w);
        }
        spfa();
        for(int u=1;u<=n;u++){
            for(int e=adj[u];e;e=nxt[e]){
                if(dis[u]+val[e]==dis[to[e]]){
                    num[to[e]]++;
                }
            }
        }
        for(int i=2;i<=n;i++)
        {
            ans*=num[i];
            ans%=mod;
        }
        cout<<ans<<endl;
    }
    
  • 相关阅读:
    jquery 读取 xml 属性等于某值的 方法
    jquery 定时器
    jquery div 滚动条 最底部
    ajax success 不能返回值解决方案 async:false
    wiki 使用说明
    thinkphp 二维码封装函数
    100本书 慢慢来读
    2013 来了
    jquery 解析 xml
    键盘按键 事件
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/10366476.html
Copyright © 2020-2023  润新知