zoukankan      html  css  js  c++  java
  • Luogu 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。

    十分玄学的就过了。。。

    //2018年4月21日20:17:14 
    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    
    const int N = 1000001;
    const int M = 2000001;
    const int mod = 100003;
    int n, m;
    
    int fir[N], edge_num, nxt[M], to[M], len[M];
    void addEdge(int x, int y, int z){
        to[++edge_num] = y;
        len[edge_num] = z;
        nxt[edge_num] = fir[x];
        fir[x] = edge_num;    
    }
    int dis[N], q[N], sum[N], inq[N];
    void SPFA(int A){
        int head=0, tail=1;
        for(int i=1; i<=n; i++)
            dis[i] = 1e9+7;
        dis[A] = 0;
        q[head] = A;
        inq[head] = 1;
        sum[A] = 1;
        while(head != tail){
            int x = q[head++];
            inq[x] = 0;
            if(head % mod == 0)
                head %= mod;
            for(int p=fir[x]; p; p=nxt[p])
                if(dis[to[p]] >= dis[x] + len[p]){
                    if(dis[to[p]] > dis[x] + len[p]) sum[to[p]] = sum[x];
                    else if(dis[to[p]] == dis[x] + len[p]){
                        sum[to[p]] = (sum[to[p]] + sum[x]) % mod;
                    }
                    dis[to[p]] = dis[x] + len[p];
                    if(!inq[to[p]]){
                        inq[to[p]] = 1;
                        q[tail++] = to[p];
                        if(tail % mod == 0) tail %= mod;
                    }
                }
            
        }
    }
    
    int main(){
        scanf("%d%d", &n, &m);
        for(int i=1; i<=m; i++){
            int x, y;
            scanf("%d%d", &x, &y); 
            addEdge(x, y, 1);
            addEdge(y, x, 1); 
        }
        SPFA(1);
        for(int i=1; i<=n; i++)
            printf("%d
    ", sum[i]);
        
        return 0;
    }
  • 相关阅读:
    【其他】UTF-8带签名与不带签名
    【Python】Python 过滤列表
    【EF】EF扩展库(批量操作)
    【python】用 sqlacodegen 将存在的数据库表 转化成model.py
    【python】使用枚举类
    【python】Python: Enum枚举的实现
    【python】python sqlalchemy core
    【python】python字符串前面加u,r,b的含义
    【EF】Entity Framework Core 2.0 特性介绍和使用指南
    Asp.Net 之 前台绑定常用总结
  • 原文地址:https://www.cnblogs.com/sineagle/p/8903620.html
Copyright © 2011-2022 走看看