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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 安全帽识别系统-智慧工地的守护者

    安全帽识别系统-智慧工地的守护者安全帽识别系统能够实时对未佩戴安全帽的行为发出警告,及时提醒监理人员处理,为作业人员筑起一道人工智能的安全防火墙。鹰眸安全帽识别系统面世之后,在业界引起了不小的震动,相关企业不但积极推广,还提出了许多建设性的意见,毕竟将人工智能的深度学习应用于视频分析还是很新的事物,那么鹰眸安全帽识别系统能做什么,在此与大家一起分享,希望起到抛砖引玉的作用。一、鹰眸安全帽识别系统通过视频实时分析工作区域,如…

    2022年5月15日
    40
  • Opencv人脸识别项目简介

    Opencv人脸识别项目简介Opencv人脸识别Project综述项目要求使用opencv实现对人脸库的主成分提取(不使用PCA类),完成特征模型保存对一张测试照片进行识别,找到图片库中和测试图片最像的图配置说明Opencv3.0VS2015Win10配置过程网上太多了,就不做过多解释了,可以参照某个教程来做。主要的也就几步,下载Opencv,配Path,配置VC++目录的包含目录和库目录,配置链接器附加项的附

    2022年6月5日
    38
  • http://bdsmdvdtube.com/ 罪恶无处不在

    http://bdsmdvdtube.com/ 罪恶无处不在http://bdsmdvdtube.com/

    2022年7月1日
    19
  • mysql批量添加数据sql语句_sql insert into 批量

    mysql批量添加数据sql语句_sql insert into 批量在MySQL数据库中,如果要插入上百万级的记录,用普通的insertinto来操作非常不现实,速度慢人力成本高,推荐使用LoadData或存储过程来导入数据,我总结了一些方法分享如下,主要基于MyISAM和InnoDB引擎。1InnoDB存储引擎首先创建数据表(可选),如果有了略过:1>CREATEDATABASEecommerce;2>USEecommerce;3&…

    2022年10月5日
    0
  • 【Linux从青铜到王者】第一篇:Linux常见指令

    【Linux从青铜到王者】第一篇:Linux常见指令系列文章目录文章目录系列文章目录前言一、Linux是什么二、Linux下基本指令1.ls指令2.pwd指令3.cd指令4.touch指令5.mkdir指令6.rmdir指令7.rm指令8.man指令9.echo指令10.cp指令2.读入数据总结前言一、Linux是什么Linux是一种自由和开放源代码的类UNIX操作系统,该操作系统的内核由林纳斯托瓦兹在1991年首次发布,之后,在加上用户空间的应用程序之后,就成为了Linux操作系统。严格来讲,Linux只是操作系统内核本身,但通常采用.

    2022年5月2日
    45
  • 动态页面和静态页面的区别

    动态页面和静态页面的区别静态页面 就是所有页面显示的内容都是写在 HTML 文件当的 如更改内容就是直接修改 HTML 文件 动态页面 就是内容不是写死在 HTML 文件当中的 页面的内容是通过像 asp php jsp cgi 格式文件 那样的编程语言输出 或编写访问数据库程序从数据库中和到的内容的 更改数据库就可以达到修改内容的目的 不用修改 HTML 文件 静态 动态的区分不是以页面有没有动画

    2025年6月6日
    0

发表回复

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

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