黑暗城堡

题目描述

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

输入格式

第一行有两个整数 N 和 M。之后 M 行,每行三个整数 X,Y 和 L,表示可以修建 X 和 Y 之间的一条长度为 L 的通道。2≤N≤1000,N – 1≤M≤N(N – 1)/2,1≤L≤100

输出格式

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


根据题意,所有边满足Di=Si的图其实就是最短路径树。

所以我们可以求出图的最短路径树。由于这个'最短路径树'其实并不是一棵树,它其实是一张DAG,所以我们还得再处理一下方案数。
首先,树的每个节点的都只有一个父亲节点。所以我们可以统计一下DAG上每个点的父亲数,再根据乘法原理,方案数就等于:

\[ \prod_{i=2}^{n}ind[x] \]

ind表示入度,也就是父亲数。i从2开始是因为1没有父亲。

那么算法的时间复杂度就是:O((N+M)log(N+M))

#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<queue>
#define maxn 1001
#define maxm 1000001
#define mod ((1<<31)-1)
using namespace std;
 
vector<int> to[maxn],w[maxn];
int dis[maxn],ind[maxn];
bool vis[maxn];
int n,m;
 
inline int read(){
    register int x(0),f(1); register char c(getchar());
    while(c<'0'||'9'<c){ if(c=='-') f=-1; c=getchar(); }
    while('0'<=c&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    return x*f;
}
 
inline void dijkstra(){
    memset(dis,0x3f,sizeof dis);
    priority_queue< pair<int,int>,vector< pair<int,int> >,greater< pair<int,int> > > q;
    q.push(make_pair(0,1)),dis[1]=0;
    while(q.size()){
        int u=q.top().second; q.pop();
        if(vis[u]) continue; vis[u]=true;
        for(register int i=0;i<to[u].size();i++){
            int v=to[u][i];
            if(dis[v]>dis[u]+w[u][i]){
                dis[v]=dis[u]+w[u][i],ind[v]=1;
                q.push(make_pair(dis[v],v));
            }else if(dis[v]==dis[u]+w[u][i]) ind[v]++;
        }
    }
}
 
int main(){
    n=read(),m=read();
    for(register int i=1;i<=m;i++){
        int u=read(),v=read(),_w=read();
        to[u].push_back(v),w[u].push_back(_w);
        to[v].push_back(u),w[v].push_back(_w);
    }
    dijkstra();
 
    long long ans=1;
    for(register int i=2;i<=n;i++) ans=(1ll*ans*ind[i])%mod;
    printf("%lld\n",ans);
    return 0;
}

转载于:https://www.cnblogs.com/akura/p/10951832.html

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是一个基本的Python海龟命令画城堡的示例代码: ```python import turtle # 设置画笔 t = turtle.Pen() t.speed(0) # 设置画笔速度为最快 # 画城堡墙壁 t.pensize(5) t.color('gray') t.begin_fill() for i in range(4): t.forward(200) t.right(90) t.end_fill() # 画城堡门 t.penup() t.goto(80, -50) t.pendown() t.color('brown') t.begin_fill() t.forward(40) t.left(90) t.forward(80) t.left(90) t.forward(40) t.left(90) t.forward(80) t.end_fill() # 画城堡旗帜 t.penup() t.goto(0, 110) t.pendown() t.color('red') t.begin_fill() t.forward(40) t.left(120) t.forward(80) t.left(120) t.forward(80) t.left(120) t.forward(40) t.end_fill() # 画城堡塔 t.penup() t.goto(-100, 0) t.pendown() t.color('gray') t.begin_fill() t.circle(50) t.end_fill() # 画城堡塔顶 t.penup() t.goto(-100, 100) t.pendown() t.begin_fill() t.color('brown') t.circle(20) t.end_fill() # 画城堡另一个塔 t.penup() t.goto(100, 0) t.pendown() t.color('gray') t.begin_fill() t.circle(50) t.end_fill() # 画城堡另一个塔顶 t.penup() t.goto(100, 100) t.pendown() t.begin_fill() t.color('brown') t.circle(20) t.end_fill() # 隐藏画笔 t.hideturtle() # 点击关闭窗口 turtle.exitonclick() ``` 代码解释: - 创建一个海龟对象t。 - 画城堡墙壁:设置画笔粗细和颜色,然后使用for循环画出四个边长为200的正方形。 - 画城堡门:使用penup()抬起画笔,goto()移动到门的位置,pendown()放下画笔,然后画出门的形状。 - 画城堡旗帜:使用penup()抬起画笔,goto()移动到旗帜的位置,pendown()放下画笔,然后画出旗帜的形状。 - 画城堡塔:使用penup()抬起画笔,goto()移动到塔的位置,pendown()放下画笔,然后画出塔的形状。 - 画城堡塔顶:使用penup()抬起画笔,goto()移动到塔顶的位置,pendown()放下画笔,然后画出塔顶的形状。 - 隐藏画笔,然后等待用户单击窗口关闭程序。 运行上述代码后,将会在窗口中画出一个城堡

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值