• Road(bzoj 2750)


    Description

    C国有n座城市,城市之间通过m条单向道路连接。一条路径被称为最短路,当且仅当不存在从它的起点到终点的另外一条路径总长度比它小。两条最短路不同,当且仅当它们包含的道路序列不同。我们需要对每条道路的重要性进行评估,评估方式为计算有多少条不同的最短路经过该道路。现在,这个任务交给了你。

    Input

    第一行包含两个正整数n、m
    接下来m行每行包含三个正整数u、v、w,表示有一条从u到v长度为w的道路

    Output

    输出应有m行,第i行包含一个数,代表经过第i条道路的最短路的数目对1000000007取模后的结果

    Sample Input

    4 4
    1 2 5
    2 3 5
    3 4 5
    1 4 8

    Sample Output

    2
    3
    2
    1

    HINT

    数据规模

    30%的数据满足:n≤15、m≤30

    60%的数据满足:n≤300、m≤1000

    100%的数据满足:n≤1500、m≤5000、w≤10000

    /*
            刚开始打的暴力,由于细节问题,挂成了10分,后来能改到50分。
            一种很容易想到的方法是DP,但是很无奈的是想不到一种更新方法能够保证拓扑序,然而Dijkstral可以记录图的拓扑序。 
            记录每个节点前后各经过了几次,然后用乘法原理得到答案。 
    */
    #include<cstdio>
    #include<iostream>
    #include<queue>
    #include<algorithm>
    #include<cstring>
    #define N 1510
    #define M 5010
    #define mod 1000000007
    #define inf 1000000000
    using namespace std;
    int head[N],dis[N],inq[N],a[N],b[N],c[N],sum[M],n,m;
    struct node{int v,w,pre;}e[M];
    struct Node{
        int id,dist;
        bool operator< (const Node&s1) const {
            return s1.dist<dist;
        }
    };priority_queue<Node> q;
    
    void add(int i,int u,int v,int w){
        e[i].v=v;e[i].w=w;e[i].pre=head[u];head[u]=i;
    }
    void Dij(int S){
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        memset(inq,0,sizeof(inq));
        for(int i=1;i<=n;i++) dis[i]=inf;int cnt=0;
        dis[S]=0;q.push((Node){S,0});
        while(!q.empty()){
            int x=q.top().id;q.pop();
            if(inq[x]) continue;
            inq[x]=1;c[++cnt]=x;
            for(int i=head[x];i;i=e[i].pre)
                if(dis[e[i].v]>dis[x]+e[i].w){
                    dis[e[i].v]=dis[x]+e[i].w;
                    q.push((Node){e[i].v,dis[e[i].v]});
                }
        }
        for(int i=1;i<=cnt;i++) b[c[i]]=1;
        a[S]=1;
        for(int i=1;i<=cnt;i++)
            for(int j=head[c[i]];j;j=e[j].pre)
                if(dis[c[i]]+e[j].w==dis[e[j].v]) a[e[j].v]+=a[c[i]],a[e[j].v]%=mod;
        for(int i=cnt;i;i--)
            for(int j=head[c[i]];j;j=e[j].pre)
                if(dis[c[i]]+e[j].w==dis[e[j].v]) b[c[i]]+=b[e[j].v],b[c[i]]%=mod;
        for(int i=1;i<=n;i++)
            for(int j=head[i];j;j=e[j].pre)
                if(dis[i]+e[j].w==dis[e[j].v]) sum[j]=(sum[j]+(long long)a[i]*b[e[j].v])%mod;
    }
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++){
            int u,v,w;scanf("%d%d%d",&u,&v,&w);
            add(i,u,v,w);
        }
        for(int i=1;i<=n;i++) Dij(i);
        for(int i=1;i<=m;i++) printf("%d
    ",sum[i]);
        return 0;
    }
  • 相关阅读:
    关于在centos下安装python3.7.0以上版本时报错ModuleNotFoundError: No module
    MSTP协议介绍和堆叠技术介绍
    RSTP技术详解
    5招解决路由黑洞
    系统批量运维管理器Fabric之部署LNMP业务环境
    系统批量运维管理器Fabric之动态获取远程目录列表
    系统批量运维管理器Fabric之查看远程主机信息
    系统批量运维管理器Fabric之基本语法篇
    系统批量运维管理器Fabric之环境搭建篇
    LightGBM 调参方法(具体操作)
  • 原文地址:https://www.cnblogs.com/harden/p/6545432.html
Copyright © 2020-2023  润新知