zoukankan      html  css  js  c++  java
  • 城堡

    【问题描述】

    给定一张n个点m条边的无向连通图,每条边有边权。我们需要从m条边中

    选出n− 1条, 构成一棵树。 记原图中从 1 号点到每个节点的最短路径长度为Di ,

    树中从 1 号点到每个节点的最短路径长度为Si ,构出的树应当满足对于任意节点

    i都有Di= Si。请你求出选出n − 1条边的方案数。

    【输入格式】

    输入的第一行包含两个整数?和?。

    接下来?行,每行包含三个整数?、?和?,描述一条连接节点?和?且边权为

    ?的边。

    【输出格式】

    输出一行,包含一个整数,代表方案数对2 ^31− 1取模得到的结果。

    【样例输入】

    3 3

    1 2 2

    1 3 1

    2 3 1

    【样例输出】

    2

    【数据规模和约定】

    2 ≤ N ≤ 5,M ≤ 10。

    对于50%的数据,满足条件的方案数不超过 10000。

    对于100%的数据,2≤ N ≤ 1000,N − 1 ≤M ≤N*(N-1)/2,1 ≤ w≤ 100。

    /*
      打的暴力,30分。
      其实正解似乎很好理解,但是没想到。
      因为当一张图只包含1-n的最短路径时,它一定是棵树,所以我们只要知道某个点它有多少边在最短路径中,然后用乘法原理乘起来。 
    */
    #include<cstdio>
    #include<iostream>
    #include<queue>
    #include<cstring>
    #define N 1010
    #define lon long long
    using namespace std;
    int head[N],vis[N],dis[N],n,m;lon c[N];
    struct node{
        int v,pre,t;
    };node e[N*N*2];
    void add(int i,int x,int y,int z){
        e[i].v=y;
        e[i].t=z;
        e[i].pre=head[x];
        head[x]=i;
    }
    void spfa(int s){
        memset(dis,127/3,sizeof(dis));
        queue<int> q;q.push(s);
        vis[s]=1;dis[s]=0;
        while(!q.empty()){
            int u=q.front();vis[u]=0;q.pop();
            for(int i=head[u];i;i=e[i].pre){
                if(dis[e[i].v]>dis[u]+e[i].t){
                    dis[e[i].v]=dis[u]+e[i].t;
                    if(!vis[e[i].v]){
                        vis[e[i].v]=1;
                        q.push(e[i].v);
                    }
                }
            }
        }
    }
    int main(){
        freopen("castle.in","r",stdin);
        freopen("castle.out","w",stdout);
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++){
            int x,y,z;scanf("%d%d%d",&x,&y,&z);
            add(i*2-1,x,y,z);add(i*2,y,x,z);
        }
        spfa(1);
        queue<int> q;q.push(1);vis[1]=1;c[1]=1LL;
        while(!q.empty()){
            int u=q.front();q.pop();
            for(int i=head[u];i;i=e[i].pre){
                if(dis[e[i].v]==dis[u]+e[i].t){
                    c[e[i].v]++;
                    c[e[i].v]%=(lon)((1LL<<31LL)-1);
                    if(!vis[e[i].v]){
                        q.push(e[i].v);
                        vis[e[i].v]=1;
                    }
                }
            }
        }
        lon ans=1;
        for(int i=1;i<=n;i++)
            ans*=c[i],ans%=(lon)((1LL<<31LL)-1);
        cout<<ans;
        return 0;
    }
  • 相关阅读:
    jquery的图片异步加载
    thinkphp3.1的验证码
    android的edittext设置输入限制,只能输入数字
    android,安卓get请求的提交以及我遇到的异常
    android安卓开发基础小笔记,添加按钮事件,打开新窗体,窗体传值,回传
    php正则表达式函数
    php对浮点数小数取整,php除法取整数
    php数组全排列,元素所有组合
    javascript数组全排列,数组元素所有组合
    spring 配置中相关属性的含义:
  • 原文地址:https://www.cnblogs.com/harden/p/6059943.html
Copyright © 2011-2022 走看看