2

一本通 1486:【例题1】黑暗城堡 题解

题目描述

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

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

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

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

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

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

输入格式

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

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

输出格式

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

AC代码

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 ll n,m,d[2020],dis[2020][2020],x,y,z,cnt[20020];
 5 bool vis[2000010];
 6 int main()
 7 {
 8     scanf("%lld%lld",&n,&m);
 9     for (int i=1;i<=n;i++)
10         for (int j=1;j<=n;j++)
11         if (i==j)    dis[i][j]=0;
12         else    dis[i][j]=1e18;
13     for (int i=1;i<=m;i++)
14     {
15         scanf("%lld%lld%lld",&x,&y,&z);
16         if (dis[x][y]>z)
17         {
18             dis[x][y]=z;
19             dis[y][x]=z;
20         }
21     }
22     for (int i=1;i<=n;i++)
23         d[i]=dis[1][i];
24     for (int i=1;i<=n;i++)
25     {
26         ll minn=1e18,k;
27         for (int j=1;j<=n;j++)
28         {
29             if (!vis[j]&&minn>d[j])
30             {
31                 minn=d[j];
32                 k=j;
33             }
34         }
35         vis[k]=1;
36         for (int j=1;j<=n;j++)
37             if (d[j]>d[k]+dis[k][j])
38             d[j]=d[k]+dis[k][j];
39     }
40     for (int i=1;i<=n;i++)
41         for (int j=1;j<=n;j++)
42         if (i!=j&&d[j]==d[i]+dis[i][j])
43             cnt[j]++;
44     ll ans=1;
45     for (int i=1;i<=n;i++)
46         if (cnt[i])
47         {
48             ans*=cnt[i];
49             ans%=2147483647;
50         }
51     printf("%lld\n",ans);
52     return 0;
53 }

 

posted @ 2021-08-25 15:55  Zˇx  阅读(346)  评论(0)    收藏  举报
Live2D