zoukankan      html  css  js  c++  java
  • 黑暗城堡(生成树)

    你知道黑暗城堡有 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;
    }
    
  • 相关阅读:
    网页中插入Flash动画(.swf)代码和常用参数设置
    关于UML中逻辑模型的工具的详细介绍
    简单CSS hack:区分IE6、IE7、IE8、Firefox、Opera
    mysql sock找不到
    简述nginx日志管理切割日志(亲测可行)
    Linux下使用rm删除文件,并排除指定文件(亲测可行)
    常驻内存以及如何避免内存泄漏
    TASK异步进程处理场景
    TCP长连接数据传输(同步方式)
    在智联上投了一个月的简历,很多都有意向,但是却没有通知我去
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/10366476.html
Copyright © 2011-2022 走看看