bzoj2750最短路计数

bzoj2750最短路计数

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2750

枚举每一个起点,通过该边的子树中有多少节点就知道本次它被经过几次了;

  因为同一起点到该边的起点的最短路唯一。

但其实不是!就在于可以有长度相等的最短路!

所以暴力通过dis[cur]+edge[ i ].w==dis[ v ]?来判断该边是否在当前最短路中。

记录从根到该边起点有多少路径时要保证指向它的点都已赋过值,所以拓扑一下。

别忘了到处写上那个暴力判断!

关于rd,别忘了赋初值。只要每次赋rd[cur]=0就行了。其它会在更新dis时赋好。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define ll long long
using namespace std;
const int N=1505,M=5005,mod=1e9+7;
int n,m,head[N],pre[N],dis[N],xnt,rd[N];
ll d1[N],d2[N],ans[M];
bool in[N];
queue<int> r;
struct Edge{
    int next,from,to,w;
    Edge(int n=0,int f=0,int t=0,int w=0):next(n),from(f),to(t),w(w) {}
}edge[M];
void spfa(int cur)
{
    memset(dis,1,sizeof dis);
    queue<int> q;
    dis[cur]=0;q.push(cur);in[cur]=1;rd[cur]=0;//
    while(q.size())
    {
        int k=q.front();q.pop();in[k]=0;
        for(int i=head[k],v;i;i=edge[i].next)
        {
            if(dis[k]+edge[i].w==dis[v=edge[i].to])rd[v]++;
            if(dis[k]+edge[i].w<dis[v=edge[i].to])
            {
                rd[v]=1;
                dis[v]=dis[k]+edge[i].w;
                if(!in[v])q.push(v),in[v]=1;
            }
        }
    }
}
void dp(int cur)
{
    d2[cur]=1;
    for(int i=head[cur],v;i;i=edge[i].next)
        if(dis[v=edge[i].to]==dis[cur]+edge[i].w)
        {
            if(!d2[v=edge[i].to])dp(v);
            (d2[cur]+=d2[v])%=mod;
        }
}
void tp(int cur)
{
    r.push(cur);
    for(int i=head[cur],v;i;i=edge[i].next)
        if(dis[v=edge[i].to]==dis[cur]+edge[i].w)//
        {
            rd[v=edge[i].to]--;
            if(!rd[v])tp(v);
        }
}
void solve(int cur)
{
//    printf("cur=%d\n",cur);
    memset(d1,0,sizeof d1);
    memset(d2,0,sizeof d2);
    while(r.size())r.pop();
    spfa(cur);
    tp(cur);
    dp(cur);
    d1[cur]=1;
    while(r.size())
    {
        int k=r.front();r.pop();
        for(int i=head[k],v;i;i=edge[i].next)
            if(dis[v=edge[i].to]==dis[k]+edge[i].w)
                (d1[v]+=d1[k])%=mod;
    }
    for(int i=1,u,v;i<=m;i++)
        if(dis[u=edge[i].from]+edge[i].w==dis[v=edge[i].to])//
        {
            (ans[i]+=d1[u]*d2[v])%=mod;
//            printf("from=%d to=%d t=%lld ans=%lld\n",edge[i].from,edge[i].to,d2[edge[i].to],ans[i]);
        }
}
int main()
{
    scanf("%d%d",&n,&m);int x,y,z;
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d%d",&x,&y,&z);
        edge[++xnt]=Edge(head[x],x,y,z);head[x]=xnt;
    }
    for(int i=1;i<=n;i++)
        solve(i);
    for(int i=1;i<=m;i++)
        printf("%lld\n",ans[i]);
    return 0;
}

 

转载于:https://www.cnblogs.com/Narh/p/8870576.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/101716.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 使用Java代码过滤掉乱码字符

    使用Java代码过滤掉乱码字符转自:http://www.cnblogs.com/en-heng/p/5320024.html最近在日志数据清洗时遇到中文乱码,如果只要有非中文字符就将该字符串过滤掉,这种方法虽简单但并不可取,因为比如像Xperia™主題、天天四川麻将Ⅱ这样的字符串也会被过滤掉。1.Unicode编码Unicode编码是一种涵盖了世界上所有语言、标点等字符的编码方式,简单一点说

    2022年6月11日
    92
  • 电容分类—等级划分「建议收藏」

    电容分类—等级划分「建议收藏」电容等级,越高越好,目前MKP电容,是最好的。

    2022年8月22日
    3
  • 程序员在哪里可以接私活(程序员私活一个月能拿多少)

    最近很郁闷,一个女粉丝找我要开发一个系统。说是很着急。但是费用不高,说自己没钱。我平时事也很多,又不是很想接。说了一大堆苦情的话,然后说自己的要求不高,没有ui要求,我就接了。但是后来,越扯越严重……上升到600块要开发一个知乎的高度。这让我想起了预算茅草屋的价格,想要别墅的效果。扯皮扯的很累,项目我已经远程调试好了,也讲解了。最后全部退款了。关键是我还整理了很多讲解的说明:既然退款,项目就不是你的了,我开发的就是我的,项目的源码就开源吧。…

    2022年4月11日
    36
  • 硬件知识指什么

    硬件知识指什么
    计算机硬件基础知识
    电脑硬件概述
    广义的硬件不是特指计算机硬件,而是指泛指一些设施、设备、材料等有形物质及无形的精神物质。
    硬件:构成电脑的物质实体,称为硬件。如主机、显示器、键盘、鼠标。
    “计算机硬件”的简称(中国大陆及香港用语,台湾叫硬体)。与“软件”相对。电子计算机系统中所有实体部件和设备的统称。从基本结构上来讲,电脑可以分为五大部分:运算器、存储器、控制器、输入设备、输出设备等。一般我们看到的电脑都是由:主机(主要部分)、输出设备(显示器)、输

    2022年7月22日
    4
  • 计算机组成原理:最详细笔记!

    计算机组成原理:最详细笔记!前言参考:《王道计算机组成原理》学习笔记总目录+思维导图2019王道考研计算机组成原理第一章计算机系统概述1.1计算机发展历程1.1.1计算机硬件的发展计算机系统=硬件+软件计算机硬件的发展:第一代计算机:(使用电子管),第二代计算机:(使用晶体管),第三代计算机:(使用较小规模的集成),第四代计算机:(使用较大规模的集成),已经经历了4代,计算机的速度越来越快,并且体积变得越来越小。发展趋势:更微型、多用途;更巨型、超高速晶体管之父:肖克利(1956年诺贝尔物

    2022年5月31日
    27
  • dos窗口编译java程序命令_dos编译java

    dos窗口编译java程序命令_dos编译java随着RESTful风格的接口普及,程序员默认都会使用json作为数据传递的方式。json格式的数据冗余少,兼容性高,从提出到现在已被广泛的使用,可以说成为了Web的一种标准。无论我们服务端使用什么语言,我们拿到json格式的数据之后都需要做jsonDecode(),将json串转换为json对象,而对象默认会存储于HashTable,而HashTable很容易被碰撞攻击。我只要将攻击数据放在j…

    2022年9月26日
    0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号