ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

洛谷P1144《最短路计数》

2020-10-14 18:31:38  阅读:229  来源: 互联网

标签:include 洛谷 int 短路 ans edge P1144 now dis


原更新日期:2019-01-12 09:57:14

最短路“板子”

题目描述

给出一个\(N\)个顶点\(M\)条边的无向无权图,顶点编号为\(1-N\)。问从顶点\(1\)开始,到其他每个点的最短路有几条。

输入输出格式

输入格式

第一行包含\(2\)个正整数\(N,M\),为图的顶点数与边数。

接下来\(M\)行,每行\(2\)个正整数\(x,y\),表示有一条顶点\(x\)连向顶点\(y\)的边,请注意可能有自环与重边。

输出格式

共\(N\)行,每行一个非负整数,第\(i\)行输出从顶点\(1\)到顶点\(i\)有多少条不同的最短路,由于答案有可能会很大,你只需要输出 \(ans \bmod 100003\)后的结果即可。如果无法到达顶点\(i\)则输出\(0\)。

输入输出样例

输入样例

5 7
1 2
1 3
2 4
3 4
2 3
4 5
4 5

输出样例

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\)。

解题思路

稍微改一下最短路板子即可

具体就是用 ans[i] 数组记录一下到i点的最短路个数,在更新路径长度的时候判一下两条路径长度的关系即可

const int HA = 100006;

/* ... */

for (int e = head[now]; e; e = edge[e].next) {
    int to = edge[e].now;
    if (dis[to] > dis[now] + edge[e].weight) {
    // 两条路径长度不等,更新答案
        dis[to] = dis[now] + edge[e].weight;
        ans[to] = ans[now];
        q.push(NewNode(dis[to], to));
    } else if (dis[to] == dis[now] + edge[e].weight) {
    	// 两条路径长度相等,将答案相加
        ans[to] += ans[now];
        ans[to] %= HA;
    }
}

代码实现

/* -- Basic Headers -- */
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cctype>
#include <algorithm>

/* -- STL Iterators -- */
#include <vector>
#include <string>
#include <stack>
#include <queue>

/* -- External Headers -- */
#include <map>
#include <cmath>

/* -- Defined Functions -- */
#define For(a,x,y) for (int a = x; a <= y; ++a)
#define Forw(a,x,y) for (int a = x; a < y; ++a)
#define Bak(a,y,x) for (int a = y; a >= x; --a)

namespace FastIO {
    
    inline int getint() {
        int s = 0, x = 1;
        char ch = getchar();
        while (!isdigit(ch)) {
            if (ch == '-') x = -1;
            ch = getchar();
        }
        while (isdigit(ch)) {
            s = s * 10 + ch - '0';
            ch = getchar();
        }
        return s * x;
    }
    inline void __basic_putint(int x) {
        if (x < 0) {
            x = -x;
            putchar('-');
        }
        if (x >= 10) __basic_putint(x / 10);
        putchar(x % 10 + '0');
    }
    
    inline void putint(int x, char external) {
        __basic_putint(x);
        putchar(external);
    }
}


namespace Solution {
    const int HA = 100003;
    
    struct Graph {
        static const int MAXN = 1000000 + 10;
        static const int MAXM = 2000000 + 10;
        
        struct Node {
            int nweight, now;
            
            Node() { nweight = now = 0; }
            
            bool operator < (const Node &that) const {
                return nweight > that.nweight;
            }
        };
        
        struct Edge {
            int now, weight, next;
        } edge[MAXM * 2];
        
        int head[MAXN], dis[MAXN], ans[MAXN], cnt;
        
        inline void addEdge(int prev, int next, int weight, bool isR = true) {
            if (isR) { addEdge(next, prev, weight, false); }
            edge[++cnt].now = next;
            edge[cnt].weight = weight;
            edge[cnt].next = head[prev];
            head[prev] = cnt;
        }
        
        inline Node NewNode(int nowWeight, int now) {
            Node tmp;
            tmp.nweight = nowWeight;
            tmp.now = now;
            return tmp;
        }
        
        inline void SPFA() {
            memset(dis, 0x7f, sizeof(dis));
            memset(ans, 0, sizeof ans);
            std::priority_queue<Node> q;
            q.push(NewNode(0, 1));
            dis[1] = 0;
            ans[1] = 1;
            while (!q.empty()) {
                Node NowNode = q.top();
                q.pop();
                int now = NowNode.now;
                for (int e = head[now]; e; e = edge[e].next) {
                    int to = edge[e].now;
                    if (dis[to] > dis[now] + edge[e].weight) {
                        dis[to] = dis[now] + edge[e].weight;
                        ans[to] = ans[now];
                        q.push(NewNode(dis[to], to));
                    } else if (dis[to] == dis[now] + edge[e].weight) {
                        ans[to] += ans[now];
                        ans[to] %= HA;
                    }
                }
            }
        }
    } g1;
    
    int n, m;
}

signed main() {
#define HANDWER_FILE
#ifndef HANDWER_FILE
    freopen("testdata.in", "r", stdin);
    freopen("testdata.out", "w", stdout);
#endif
    using namespace Solution;
    using FastIO::getint;
    n = getint();
    m = getint();
    For (i, 1, m) {
        int prev = getint();
        int next = getint();
        g1.addEdge(prev, next, 1);
    }
    g1.SPFA();
    For (i, 1, n) {
        FastIO::putint(g1.ans[i], '\n');
    }
    return 0;
}


标签:include,洛谷,int,短路,ans,edge,P1144,now,dis
来源: https://www.cnblogs.com/handwer/p/13816502.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有