• 16.1113 模拟考试T3


    城堡
    【问题描述】
    给定一张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数组全部乘起来并且取模。

  • 相关阅读:
    ubutu16.04编译安装apache
    python格式化字符串
    git服务器搭建
    merge into 导致序列跳号
    Apache 强制SSL访问
    pyhton之解析html的表格
    Two modules in a project cannot share the same content root报错解决方案
    hdoj
    hdoj
    QHUOJ
  • 原文地址:https://www.cnblogs.com/suishiguang/p/6058828.html
Copyright © 2020-2023  润新知