• 最短路计数(洛谷 1144)


    题目描述

    给出一个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 ≤ 100000,M ≤ 200000。

    /*
      记录最短路的条数,一开始不知道怎么做,难道要进行n++遍spfa?
      后来一思考,完全可以设一个数组f来做,在进行spfa更新dis时顺便把f更新了。
      更新方法:
        当到达i节点这条路与原来的路长度相同时,f[i]+=f[father];
        当这条路比原来的路径短的时候,f[i]=f[father]。 
    */
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #define M 100010
    #define mod 100003
    using namespace std;
    struct node
    {
        int v,pre;
    };node e[M*4];
    int head[M],dis[M],f[M],q[M*2],vis[M],n,m;
    void add(int i,int x,int y)
    {
        e[i].v=y;
        e[i].pre=head[x];
        head[x]=i;
    }
    void spfa()
    {
        int t=0,w=1;
        q[1]=1;
        vis[1]=1;
        dis[1]=0;
        f[1]=1;
        while(t<w)
        {
            int u=q[++t];
            vis[u]=0;
            for(int i=head[u];i;i=e[i].pre)
              if(dis[u]+1<=dis[e[i].v])
              {
                  if(dis[u]+1<dis[e[i].v])
                  f[e[i].v]=f[u];
                else f[e[i].v]+=f[u],f[e[i].v]%=mod;
                  dis[e[i].v]=dis[u]+1;
                  if(!vis[e[i].v])
                  {
                      vis[e[i].v]=1;
                      q[++w]=e[i].v;
                  }
              }
        }
    }
    int main()
    {
        memset(dis,0x3f3f3f3f,sizeof(dis));
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            add(i*2-1,x,y);add(i*2,y,x);
        }
        spfa();
        for(int i=1;i<=n;i++)
          printf("%d
    ",f[i]%mod);
        return 0;
    }
    View Code
  • 相关阅读:
    KVM虚拟化网卡管理
    KVM虚拟化存储管理
    OpenStack简介
    KVM虚拟机管理
    Jenkins持续集成
    Python函数
    Python文件处理
    Python语句
    Python数据类型的用法
    微信服务号开发小项目总结
  • 原文地址:https://www.cnblogs.com/harden/p/5799490.html
Copyright © 2020-2023  润新知