• 洛谷P1144 最短路计数


     P1144 最短路计数

      • 205通过
      • 739提交
    • 题目提供者该用户不存在
    • 标签图论
    • 难度普及+/提高

    提交该题 讨论 题解 记录

    最新讨论

    • 数据有毒
    • 求神犇
    • 无向图无向图无向图
    • help

    题目描述

    给出一个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。

    分析:这道题有一个陷阱:告诉你一条边是u连向v,很容易认为是有向边,其实是无向边......既然是无向边,边权为1,那么就bfs一下.如果求到达点u的最短路的个数呢?设现在求到的最短路为v,如果从1到i到u的距离正好为v,那么点u的个数则应该加上点i的个数,同时要注意取模.

    #include <cstdio>
    #include <queue>
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    
    using namespace std;
    
    const int maxn = 1000010,mod = 100003;
    int head[maxn], to[maxn * 2], nextt[maxn * 2],tot,vis[maxn],d[maxn];
    int n, m, cnt[maxn];
    
    void add(int a, int b)
    {
        tot++;
        to[tot] = b;
        nextt[tot] = head[a];
        head[a] = tot;
    }
    
    void bfs()
    {
        queue <int> q;
        q.push(1);
        d[1] = 0;
        cnt[1] = 1;
        vis[1] = 1;
        while (!q.empty())
        {
            int u = q.front();
            q.pop();
            for (int i = head[u];i;i = nextt[i])
            {
                int v = to[i];
                if (!vis[v])
                {
                    vis[v] = 1;
                    q.push(v);
                    d[v] = d[u] + 1;
                    cnt[v] = cnt[u];
                }
                else
                    if (d[v] == d[u] + 1)
                        cnt[v] = (cnt[u] + cnt[v]) % mod;
            }
        }
    }
    
    int main()
    {
        scanf("%d%d", &n, &m);
        for (int i = 1; i <= m; i++)
        {
            int u, v;
            scanf("%d%d", &u, &v);
            add(u, v);
            add(v, u); 
        }
        bfs();
        for (int i = 1; i <= n; i++)
            printf("%d
    ", cnt[i]);
    
        return 0;
    }
  • 相关阅读:
    C++ 纸牌 今日头条面试题
    c++ 病句 今日头条面试题
    C++ 球迷 今日头条面试题
    C++ 活动安排
    C++ 弗洛伊德算法
    填坑 bzoj3337
    bzoj3884 上帝与集合的正确用法
    人参中第一次膜你退货
    洛谷P2216 [HAOI2007]理想的正方形
    洛谷 P1099 树网的核+P2491 [SDOI2011]消防
  • 原文地址:https://www.cnblogs.com/zbtrs/p/5796251.html
Copyright © 2020-2023  润新知