• LOJ10064黑暗城堡


    题目描述
    你知道黑暗城堡有 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 取模之后的结果。

    样例
    样例输入
    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。

    而不同的城堡修建方案数对 2^{31} -1 取模之后的结果为 6。

    数据范围与提示
    对于全部数据,1≤N≤1000,1≤M≤N(N−1)/2​,1≤l≤200。

    ——————————————————————————————————————————

    这是一道很神的题。

    首先dij,求出1号点到其他点的最短距离。

    然后扫描所有边,如果dis[v]==dis[u]+e[i].w,说明让v点的距离为给最短距离的路径又多了一条,所以,cnt[v]++;

    最终结果就是所有点的cnt[]相乘。

    !!!!!!!!!!!!

    。。。。。。。。。。。。。。。

    ——————————————————————————————————————————

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 long long mod=((long long)1<<31)-1;
     4 const int maxn=1010;
     5 const int maxm=5e5;
     6 int n,m;
     7 struct edge
     8 {
     9     int u,v,w,nxt;
    10 }e[maxm<<1];
    11 int head[maxn],js;
    12 void addage(int u,int v,int w)
    13 {
    14     e[++js].u=u;e[js].v=v;e[js].w=w;
    15     e[js].nxt=head[u];head[u]=js;
    16 }
    17 int dis[maxn];
    18 bool vis[maxn];
    19 struct node
    20 {
    21     int dis,p;
    22     bool operator < (node b)const
    23     {
    24         return dis>b.dis;
    25     }
    26 };
    27 priority_queue< node > q;
    28 void dij()
    29 {
    30     memset(dis,0x7f,sizeof(dis));
    31     dis[1]=0;
    32     q.push((node){0,1});
    33     while(!q.empty())
    34     {
    35         node tp=q.top();
    36         q.pop();
    37         int u=tp.p;
    38         if(vis[u])continue;
    39         vis[u]=1;
    40         for(int i=head[u];i;i=e[i].nxt)
    41         {
    42             int v=e[i].v;
    43             if(dis[u]+e[i].w<dis[v])
    44             {
    45                 dis[v]=dis[u]+e[i].w;
    46                 q.push((node){dis[v],v});
    47             }
    48         }
    49     }        
    50 }
    51 int cnt[maxn];
    52 long long ans=1;
    53 int main()
    54 {
    55     scanf("%d%d",&n,&m);
    56     for(int u,v,w,i=0;i<m;++i)
    57     {
    58         scanf("%d%d%d",&u,&v,&w);
    59         addage(u,v,w);addage(v,u,w);
    60     }
    61     dij();
    62     for(int j=1;j<=n;++j)
    63         for(int i=head[j];i;i=e[i].nxt)
    64             if(dis[e[i].v]==dis[e[i].u]+e[i].w)cnt[e[i].v]++;
    65         for(int i=2;i<=n;++i)ans=ans*cnt[i]%mod;
    66     cout<<ans;
    67     return 0;
    68 }
    View Code
  • 相关阅读:
    一、JDBC操作
    十五、时间日期类
    十四、字符串详解
    源文件
    十六、·实现显示所有雇员
    十五、抽象出基础接口
    十四、增加EmployeeService实现用户添加
    十三、解决懒加载
    python __new__以及__init__
    Python的getattr(),setattr(),delattr(),hasattr()及类内建__getattr__应用
  • 原文地址:https://www.cnblogs.com/gryzy/p/10481998.html
Copyright © 2020-2023  润新知