• Gym100889L


    Gym100889L
    https://vjudge.net/problem/341988/origin
    题目大意:有一个n*n的图,m条双向边(没有重边自环),求从每个节点出发走k条路后到其他所有节点的最短距离和方案数,方案数取模1e9+7输出
    做法:传递闭包,走k条路,就是做k次矩阵乘法,所谓矩阵乘法就是做floyed+最短路计数,做矩阵乘法的时候用快速幂

    #include <iostream>
    #include <cstdio>
    #include <queue>
    #include <algorithm>
    #include <cmath>
    #include <cstring>
    #define inf 2147483647
    #define N 1000010
    #define mod 1000000007
    #define p(a) putchar(a)
    #define For(i,a,b) for(register long long i=a;i<=b;++i)
    //by war
    //2019.7.31
    using namespace std;
    long long n,m,k;
    long long x,y,v;
    struct matrix{
        long long dis[160][160];
        long long sum[160][160];
        void init(){
            For(i,1,n)
                For(j,1,n)
                    dis[i][j]=inf,sum[i][j]=0;
        }
        matrix operator * (const matrix&b)const{
            matrix r;
            r.init();
            For(k,1,n)
                For(i,1,n)
                    For(j,1,n)
                        if(dis[i][k]!=inf && b.dis[k][j]!=inf){
                            if(r.dis[i][j]>dis[i][k]+b.dis[k][j]){
                                r.dis[i][j]=dis[i][k]+b.dis[k][j];
                                r.sum[i][j]=sum[i][k]*b.sum[k][j]%mod;
                            }
                            else
                                if(r.dis[i][j]==dis[i][k]+b.dis[k][j]){
                                    r.sum[i][j]+=sum[i][k]*b.sum[k][j];
                                    r.sum[i][j]%=mod;
                                }
                        }
            return r;
        }
    }r;
    
    void in(long long &x){
        long long y=1;char c=getchar();x=0;
        while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
        while(c<='9'&&c>='0'){ x=(x<<1)+(x<<3)+c-'0';c=getchar();}
        x*=y;
    }
    void o(long long x){
        if(x<0){p('-');x=-x;}
        if(x>9)o(x/10);
        p(x%10+'0');
    }
    
    matrix ksm(matrix a,long long b){
        matrix r=a;b--;
        while(b>0){
            if(b&1)
                r=r*a;
            a=a*a;
            b>>=1;
        }
        return r;
    }
    
    int main(){
        in(n);in(m);in(k);
        r.init();
        For(i,1,m){
            in(x);in(y);in(v);
            r.dis[x][y]=v;
            r.dis[y][x]=v;
            r.sum[x][y]=1;
            r.sum[y][x]=1;
        }
        r=ksm(r,k);
        For(i,1,n){
            For(j,1,n)
                if(r.dis[i][j]==inf)
                    printf("X %lld ",r.sum[i][j]);
                else
                    printf("%lld %lld ",r.dis[i][j],r.sum[i][j]);
            p('
    ');
        }
        return 0;
    }
  • 相关阅读:
    LockFile文件-解决并发写入日志的问题
    二、Consul Service Mesh
    查看CPU和内存,用机器指令和汇编指令编程
    环境配置过程中的一些小tips
    工具使用指北:GDB
    瞧瞧我发现了什么
    新的目标:Capture The Flag
    python 实现的idw插值方法
    Python 利用 百度接口输入地点名字返回经纬度
    轻松搞定javascript变量(闭包,预解析机制,变量在内存的分配 )
  • 原文地址:https://www.cnblogs.com/war1111/p/11279807.html
Copyright © 2020-2023  润新知