zoukankan      html  css  js  c++  java
  • 洛谷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;
    }
  • 相关阅读:
    面向对象第三次总结性博客
    面向对象程序设计lesson2心得体会
    面向对象程序设计先导课程心得体会
    面向对象程序设计先导lesson1心得体会
    Git 学习笔记
    asp.net 的Eval日期時間怎麼格式化
    正則表達式(轉)
    要等彈出窗口顯示信息後,点击确定再跳轉到其他頁面
    彈出窗口,確定再刪除數據
    SQL SERVER 2008中的兩種潛換字符方法
  • 原文地址:https://www.cnblogs.com/zbtrs/p/5796251.html
Copyright © 2011-2022 走看看