YBT1486 黑暗城堡
题目
1486:【例题1】黑暗城堡
时间限制: 1000 ms 内存限制: 65536 KB
提交数: 1248 通过数: 431
【题目描述】
知道黑暗城堡有 N 个房间,M 条可以制造的双向通道,以及每条通道的长度。
城堡是树形的并且满足下面的条件:
设 Di为如果所有的通道都被修建,第 i 号房间与第 1 号房间的最短路径长度;
而 Si 为实际修建的树形城堡中第 i 号房间与第 1 号房间的路径长度;
要求对于所有整数 i(1≤i≤N),有 Si=Di 成立。
你想知道有多少种不同的城堡修建方案。当然,你只需要输出答案对 231−1 取模之后的结果就行了。
【输入】
第一行为两个由空格隔开的整数 N,M;
第二行到第 M+1 行为 3 个由空格隔开的整数 x,y,l:表示 x 号房间与 y 号房间之间的通道长度为 l。
【输出】
一个整数:不同的城堡修建方案数对 231−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。
而不同的城堡修建方案数对 231−1 取模之后的结果为 6。
数据范围:
对于全部数据,1≤N≤1000,1≤M≤N(N−1)2,1≤l≤200。
解法
- 用spfa求出点1到各个点的最短路径di
- 对每个点搞出可实现最短路的方法ci
- 乘法原理将ci相乘得到最终结果
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| #include<iostream> #include<cstdio> #include<cmath> #include<string> #include<cstring> #include<algorithm> #include<vector> #include<queue> #include<stack> #include<map> using namespace std; int mod=1<<31; struct line{ int x; int l; }; vector<struct line>road[1010]; int dis[1010]; queue<struct line>q; int main(){
int n,m; mod=~mod; scanf("%d%d",&n,&m); for(int i=0;i<m;++i){ struct line a; int b; scanf("%d%d%d",&b,&a.x,&a.l); road[b].push_back(a); swap(b,a.x); road[b].push_back(a); } memset(dis,0x3f,sizeof(dis)); struct line temp; temp.x=1; temp.l=0; q.push(temp); while(!q.empty()){ temp=q.front(); q.pop(); int x=temp.x; int l=temp.l; if(l<dis[x])dis[x]=l; else continue; for(int i=0;i<road[x].size();++i){ temp=road[x][i]; temp.l+=dis[x]; q.push(temp); } } long long ans=1; for(int i=2;i<=n;++i){ int con=0; for(int j=0;j<road[i].size();++j){ if(dis[road[i][j].x]+road[i][j].l==dis[i])++con; } ans=((ans%mod)*(con%mod)%mod); } printf("%d",ans); return 0; }
|