16.1113 模拟考试T3
2017-03-17 16:13
330 查看
城堡
【问题描述】
给定一张N个点M条边的无向连通图,每条边有边权。我们需要从M条边中
选出N − 1条, 构成一棵树。 记原图中从 1 号点到每个节点的最短路径长度为?Di ,
树中从 1 号点到每个节点的最短路径长度为Si ,构出的树应当满足对于任意节点
i,都有Di = Si 。
请你求出选出N − 1条边的方案数。
【输入格式】
输入的第一行包含两个整数N和M。
接下来M行,每行包含三个整数u、v和w,描述一条连接节点u和v且边权为
w的边。
【输出格式】
输出一行,包含一个整数,代表方案数对2^31 − 1取模得到的结果。
【样例输入】
3 3
1 2 2
1 3 1
2 3 1
【样例输出】
2
【数据规模和约定】
对于30%的数据 2 ≤ N ≤ 5,M ≤ 10。
对于50%的数据,满足条件的方案数不超过 10000。
对于100%的数据,2≤ N ≤ 1000,N − 1 ≤ M ≤
N(N−1)/2,
1 ≤ w ≤ 100。
思路:两遍SPFA,第一遍求出dis[],第二遍的时候求出没个点可以有几条最短路得来,(++c[i]),之后,根据乘法原理,c数组全部乘起来并且取模。
【问题描述】
给定一张N个点M条边的无向连通图,每条边有边权。我们需要从M条边中
选出N − 1条, 构成一棵树。 记原图中从 1 号点到每个节点的最短路径长度为?Di ,
树中从 1 号点到每个节点的最短路径长度为Si ,构出的树应当满足对于任意节点
i,都有Di = Si 。
请你求出选出N − 1条边的方案数。
【输入格式】
输入的第一行包含两个整数N和M。
接下来M行,每行包含三个整数u、v和w,描述一条连接节点u和v且边权为
w的边。
【输出格式】
输出一行,包含一个整数,代表方案数对2^31 − 1取模得到的结果。
【样例输入】
3 3
1 2 2
1 3 1
2 3 1
【样例输出】
2
【数据规模和约定】
对于30%的数据 2 ≤ N ≤ 5,M ≤ 10。
对于50%的数据,满足条件的方案数不超过 10000。
对于100%的数据,2≤ N ≤ 1000,N − 1 ≤ M ≤
N(N−1)/2,
1 ≤ w ≤ 100。
1 #include<cstdio> 2 #include<cstring> 3 #include<cstdlib> 4 #include<queue> 5 using namespace std; 6 typedef long long ll; 7 const int N=1000; 8 const int M=499500; 9 const int INFI=12345678; 10 const ll mod = (1LL<<31)-1LL; 11 struct node{ 12 int next,node,w; 13 }e[M*2]; 14 ll c[N+1],ans; 15 int n,m,x,y,w,head[N+1],tot,dis[N+1]; 16 bool exist[N+1]; 17 void add_edge(int a,int b,int w){ 18 e[++tot].next=head[a]; 19 head[a]=tot;e[tot].node=b;e[tot].w=w; 20 } 21 inline void SPFA(int s) 22 { 23 queue<int> que; 24 for(int i=1;i<=n;i++) dis[i]=0x3f; 25 dis[s]=0;exist[s]=true;que.push(s); 26 while(!que.empty()) 27 { 28 int cur=que.front(); 29 exist[cur]=false;que.pop(); 30 for(int i=head[cur];i;i=e[i].next) 31 { 32 int node=e[i].node; 33 if(dis[node]>dis[cur]+e[i].w){ 34 dis[node]=dis[cur]+e[i].w; 35 if(!exist[node]) 36 exist[node]=true,que.push(node); 37 } 38 } 39 } 40 } 41 int main() 42 { 43 freopen("castle.in","r",stdin); 44 freopen("castle.out","w",stdout); 45 scanf("%d%d",&n,&m); 46 for(int i=1;i<=m;i++){ 47 scanf("%d%d%d",&x,&y,&w);add_edge(x,y,w);add_edge(y,x,w); 48 } 49 SPFA(1); 50 queue<int> q;q.push(1),exist[1]=true,c[1]=1LL; 51 while(!q.empty()){ 52 int cur=q.front();q.pop(); 53 for(int i=head[cur];i;i=e[i].next){ 54 int node=e[i].node; 55 if(dis[node]==dis[cur]+e[i].w){ 56 ++c[node]; 57 if(c[node]>=mod) c[node]-=mod; 58 if(!exist[node]) q.push(node),exist[node]=true; 59 } 60 } 61 } 62 ans=1LL; 63 for(int i=1;i<=n;i++){ 64 ans*=c[i]; 65 if(ans>=mod) ans%=mod; 66 } 67 printf("%d",(int)ans); 68 fclose(stdin); 69 fclose(stdout); 70 return 0; 71 }
思路:两遍SPFA,第一遍求出dis[],第二遍的时候求出没个点可以有几条最短路得来,(++c[i]),之后,根据乘法原理,c数组全部乘起来并且取模。
相关文章推荐
- 16.1113 模拟考试T3
- 16.1113 模拟考试T2
- 16.1113 模拟考试T2
- 16.1113 模拟考试T1
- 红十字会急救证模拟考试系统-介绍
- 清北学堂2018年1月省选强化班模拟考试1
- 2018腾讯模拟考试,移动客户端开发岗
- 驾驶人科目一模拟考试系统破解(驾照模拟考试软件破解)纪要
- 模拟考试1 BestCoder Round #2 TIANKENG’s restaurant
- 16.1114 模拟考试T1
- 2016腾讯校园招聘模拟考试(2016.03.25)
- 2017.9.15 模拟考试
- DAY2 模拟考试第三题 情书的代价
- 2017.9.22 模拟考试 解题报告
- NOIP2017 模拟考试day1 2017.10.06
- 第十七周OJ期末模拟考试项目
- 咸阳市驾照模拟考试
- 计算机等级考试二级C++上机模拟试题11套汇总及答案解释(一)
- 藏文驾驶考试模拟软件
- 考无忧2014职称计算机模拟考试题库软件 逆向分析研究: