洛谷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\n", cnt[i]);

    return 0;
}

 

posted @ 2016-08-22 17:01  zbtrs  阅读(349)  评论(0编辑  收藏  举报