当前位置: 首页 > news >正文

洛谷——P1144 最短路计数

P1144 最短路计数

题目描述

给出一个N个顶点M条边的无向无权图,顶点编号为1~N。问从顶点1开始,到其他每个点的最短路有几条。

输入输出格式

输入格式:

 

输入第一行包含2个正整数N,M,为图的顶点数与边数。

接下来M行,每行两个正整数x, y,表示有一条顶点x连向顶点y的边,请注意可能有自环与重边。

 

输出格式:

 

输出包括N行,每行一个非负整数,第i行输出从顶点1到顶点i有多少条不同的最短路,由于答案有可能会很大,你只需要输出mod 100003后的结果即可。如果无法到达顶点i则输出0。

 

输入输出样例

输入样例#1:
5 7
1 2
1 3
2 4
3 4
2 3
4 5
4 5
输出样例#1:
1
1
1
2
4

说明

1到5的最短路有4条,分别为2条1-2-4-5和2条1-3-4-5(由于4-5的边有2条)。

对于20%的数据,N ≤ 100;

对于60%的数据,N ≤ 1000;

对于100%的数据,N<=1000000,M<=2000000。

 

变形的spfa(说白了就是一个bfs),在进行最短路查询的时候判断是否出现了距离相同的路径。

#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 2000000
#define mod 100003
using namespace std;
queue<int>q;
bool vis[N];
int n,m,x,y,tot,head[N],ans[N],dis[N];
int read()
{
    int x=0,f=1; char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
    return x*f;
}
struct Edge
{
    int to,next,from;
}edge[N<<1];
int add(int x,int y)
{
    tot++;
    edge[tot].to=y;
    edge[tot].next=head[x];
    head[x]=tot;
}
int main()
{
    n=read(),m=read();
    for(int i=1;i<=m;i++)
     x=read(),y=read(),add(x,y),add(y,x);
    memset(dis,0x3f3f3f3f,sizeof(dis));
    q.push(1),dis[1]=0,vis[1]=true;ans[1]=1;
    while(!q.empty())
    {
        x=q.front();q.pop();vis[x]=false;
        for(int i=head[x];i;i=edge[i].next)
        {
            int to=edge[i].to;
            if(dis[to]>dis[x]+1)
            {
                dis[to]=dis[x]+1;
                ans[to]=ans[x]%mod;
                if(!vis[to])
                {
                    vis[to]=true;
                    q.push(to);
                }
            }
            else if(dis[to]==dis[x]+1)
            {
                ans[to]=(ans[x]+ans[to])%mod;
                if(!vis[to])
                {
                    vis[to]=true;
                    q.push(to);
                }
            }
        }
    }
    for(int i=1;i<=n;i++)
     printf("%d\n",ans[i]);
    return 0;
}
#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#include<queue>
#include<cstdlib>
using namespace std;
struct Edge//邻接表存边
{
    int t;
    int nexty;
}edge[3000000];
int head[2000000]={0};//邻接表的东东(存以i为发出点的编号最大的边的编号)……有人不懂吗
int cnt=0;
inline void add(int a,int b)//邻接表添加边
{
    cnt++;
    edge[cnt].t=b;
    edge[cnt].nexty=head[a];
    head[a]=cnt;
}
int js[2000000]={0};//每一个点的最短路径条数
int rdjs[2000000]={0};//用来避免重复的统计表,存当前在队列中,到节点i的最短路径条数
int dis[2000000];//存最短路径
bool in[2000000]={0};//是否在队列中
queue<int>spfa;//SPFA所用队列
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    int a,b;
    for(int i=0;i<m;i++)
    {
        scanf("%d%d",&a,&b);
        add(a,b);
        add(b,a);//存边
    }
    for(int i=1;i<=n;i++)dis[i]=2e9;
    dis[1]=0;//初始化dis
    in[1]=true;
    js[1]=1;//1到1最短路径1条
    rdjs[1]=1;//此次队列中,到1的最短路径条数为1
    spfa.push(1);//将1加入队列
    int curr;
    while(!spfa.empty())
    {
        curr=spfa.front();//更新发出点
        for(int i=head[curr];i!=0;i=edge[i].nexty)//遍历出发边
        {
            if(dis[edge[i].t]>dis[curr]+1)//若最短路有变
            {
                dis[edge[i].t]=dis[curr]+1;//更新最短路
                rdjs[edge[i].t]=js[edge[i].t]=rdjs[curr]%100003;//以前的计数均舍弃,更新到出发点的到达路径条数
                if(!in[edge[i].t])
                {//加入队列

                    in[edge[i].t]=true;
                    spfa.push(edge[i].t);
                }
            }
            else
            if(dis[edge[i].t]==dis[curr]+1)//若又有一条最短路
            {
                js[edge[i].t]=(js[edge[i].t]+rdjs[curr])%100003;//增加最短路个数
                rdjs[edge[i].t]=(rdjs[edge[i].t]+rdjs[curr])%100003;//在rdjs上更新,避免重复
                if(!in[edge[i].t])
                {//入队
                    in[edge[i].t]=true;
                    spfa.push(edge[i].t);
                }
            }
        }
        in[curr]=false;
        rdjs[curr]=0;//此次的最短路统计已用完,将此节点的最短路条数初始化,避免重复(在此题中似乎并没有什么用)
        spfa.pop();//出队
    }
    for(int i=1;i<=n;i++)printf("%d\n",js[i]);//输出
    return 0;
}
比较详细一点的题解

 

转载于:https://www.cnblogs.com/z360/p/7576640.html

相关文章:

  • centos7 samba匿名访问设置
  • kafka基础知识点
  • 来来来!游戏场景风格暴露你的年纪
  • pandas模块学习笔记1--数据结构
  • Hadoop安装
  • VMware + JunOS + Linux 搭建安全测试平台
  • SecureCRT复制粘贴快捷键
  • hexo博客同步管理及迁移
  • WM_MOUSEWHEEL、WM_LBUTTONDOWN等父子窗口消息传递陷阱
  • 使用IntelliJ IDEA 配置Maven(入门)
  • 软件项目中的成本构成及估算方法【转】
  • windows下node配置npm全局路径(踩坑)
  • springmvc入门程序
  • SQServer查询数据库所有触发器
  • 流水线生产,精益生产,TPS和TOC的缓冲管理
  • 时间复杂度分析经典问题——最大子序列和
  • 【comparator, comparable】小总结
  • docker-consul
  • vue的全局变量和全局拦截请求器
  • 欢迎参加第二届中国游戏开发者大会
  • 基于OpenResty的Lua Web框架lor0.0.2预览版发布
  • 如何设计一个微型分布式架构?
  • 设计模式走一遍---观察者模式
  • 如何用纯 CSS 创作一个菱形 loader 动画
  • ​TypeScript都不会用,也敢说会前端?
  • # 日期待t_最值得等的SUV奥迪Q9:空间比MPV还大,或搭4.0T,香
  • (+4)2.2UML建模图
  • (12)Hive调优——count distinct去重优化
  • (3)llvm ir转换过程
  • (Python第六天)文件处理
  • (笔记)Kotlin——Android封装ViewBinding之二 优化
  • (超详细)语音信号处理之特征提取
  • (二)【Jmeter】专栏实战项目靶场drupal部署
  • (每日持续更新)jdk api之FileFilter基础、应用、实战
  • (五)Python 垃圾回收机制
  • (正则)提取页面里的img标签
  • .net反混淆脱壳工具de4dot的使用
  • .net中调用windows performance记录性能信息
  • @四年级家长,这条香港优才计划+华侨生联考捷径,一定要看!
  • [ 数据结构 - C++] AVL树原理及实现
  • [android] 看博客学习hashCode()和equals()
  • [Arduino学习] ESP8266读取DHT11数字温湿度传感器数据
  • [bug总结]: Feign调用GET请求找不到请求体实体类
  • [C++] sqlite3_get_table 的使用
  • [C++]18:set和map的使用
  • [Foreman]解决Unable to find internal system admin account
  • [ISCTF 2023]——Web、Misc较全详细Writeup、Re、Crypto部分Writeup
  • [java基础揉碎]方法的重写/覆盖
  • [LuoguP1141]01迷宫
  • [MySQL]日期和时间函数
  • [NSSRound#16 Basic]RCE但是没有完全RCE
  • [Oh My C++ Diary]带参数的main()函数
  • [PHP]加密解密函数
  • [Python进阶] 识别验证码
  • [PyTorch][chapter 8][李宏毅深度学习][Back propagation]