黑暗城堡(生成树)

你知道黑暗城堡有 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;
}
原文地址:https://www.cnblogs.com/stargazer-cyk/p/10366476.html