首页 > 其他分享 >P1144 最短路计数 题解

P1144 最短路计数 题解

时间:2023-10-02 09:24:32浏览次数:49  
标签:pre int 题解 短路 P1144 pair dp

Problem

考察算法:拓扑排序 + \(DP\) + \(Dijkstra\)。

题目简述

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

思路

  • 先求出 \(1\) 号点到每个点的最短路 \(d_i\) 。

  • 分析每条边 $(x,y) $:

    如果 d[x] + 1 == d[y]:这条边有用。

  • 将所有有用的边拓扑排序。

  • 处理队列里面的每一个点 \(x\) ,\(dp_[i] = 1\) ,枚举 \(x\) 所有的出边 \(u\) ,\(dp_u += dp_x\)。

  • 记住要边加边取余数!

代码

#include <bits/stdc++.h>

using namespace std;

const int N = 2e6 + 10, MOD = 100003;
typedef pair<int, int> PII;
struct node {
    int from, to, next;
} a[N * 2];
int pre[N], k, in[N], flag[N];
queue<int> q;

int n, m, x, y, d[N], dp[N];
bool f[N];

void add(int x, int y) {
    a[++k] = (node) {x, y, pre[x]};
    pre[x] = k;
}

void Dijkstra() {
    priority_queue<PII, vector<PII>, greater<PII> > q;
    memset(d, 0x3f, sizeof(d));
    d[1] = 0;
    q.push(make_pair(0, 1));
    while (!q.empty()) {
        PII h = q.top();
        q.pop();
        int dis = h.first, p = h.second;
        if (f[p]) continue;
        f[p] = true;
        for (int i = pre[p]; i; i = a[i].next) {
            int to = a[i].to;
            if (d[p] + 1 < d[to]) {
                d[to] = d[p] + 1;
                q.push(make_pair(d[to], to));
            }
        }
    }
}

int main() {
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= m; i++) {
        scanf("%d%d", &x, &y);
        add(x, y);
        add(y, x);
    }
    Dijkstra();
    for (int i = 1; i <= k; i++) {
        if (d[a[i].to] - d[a[i].from] == 1) {
            flag[i] = 1;
            in[a[i].to]++;
        }
    }
    for (int i = 1; i <= n; i++) {
        if (!in[i]) {
            if (d[i] != 0x3f3f3f3f)
                dp[i] = 1;
            q.push(i);
        }
    }
    while (!q.empty()) {
        int h = q.front();
        q.pop();
        for (int i = pre[h]; i; i = a[i].next) {
            if (!flag[i]) continue;
            int to = a[i].to;
            dp[to] = (dp[h] + dp[to]) % MOD;
            in[to]--;
            if (!in[to]) q.push(to);
        }
    }
    for (int i = 1; i <= n; i++) {
        printf("%d\n", dp[i]);
    }
    return 0;
}

标签:pre,int,题解,短路,P1144,pair,dp
From: https://www.cnblogs.com/yhx0322/p/17739709.html

相关文章

  • 853. 有边数限制的最短路
    第一版err#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<queue>#include<cmath>#defineN505usingnamespacestd;intn,m,k,dis[N],cnt,hd[N],vis[N],x,y,z;structEdge{intto,nxt......
  • [POI2003] Monkeys 题解
    [POI2003]Monkeys题解正着做貌似不好做,发现猴子是否掉落取决于“最后一根稻草”,也就是最后撒手的那个猴子,那我们考虑倒着把猴子网拼回去。这样,每群猴子掉落的时刻就是与\(1\)号猴子连通的时刻。利用并查集可以维护猴子的连通性,但是怎么更新答案呢?这里用vector进行了一个猴......
  • CF1874C Jellyfish and EVA 题解
    题意给定一个有向无环图,对于任意一条边\((u_i,v_i)\),有\(u_i<v_i\)。定义一次从节点\(u\)开始的移动为如下过程:\(\tt{Alice}\)选择从\(u\)出发的且未被删除的一条边。\(\tt{Bob}\)在从\(u\)出发的且未被删除的边中等概率随机选择一条。若两人选择的边相同......
  • P1126 机器人搬重物 题解
    Problem题目概括$n\timesm$的网格,有些格子是障碍格。\(0\)无障碍,\(1\)有障碍。机器人有体积,总是在格点上。有5种操作:向前移动\(1/2/3\)步左转\(/\)右转每次操作需要\(1\)秒。求从\(x_1,y_1\)到\(x_2,y_2\)点的最短路。机器人有一个初始方向$......
  • P1182 数列分段 Section II 题解
    Problem考察知识点:二分、贪心。题目描述对于给定的一个数组,现要将其分成\(M\)段,并要求每段连续,且每段和的最大值最小。思路二分答案出每段和最大值的最小值,然后贪心检验是否满足。难点在\(check\)上。策略:每次开始循环,如果没有超范围,就一直选,知道选满为止,求最大值。代......
  • Codeforces 1278D 题解
    题目大意题目大意给你\(n\)(\(1\leqslantn\leqslant5\cdot10^5\))条线段\([l_1,r_1],[l_2,r_2],\cdots,[l_n,r_n]\)(\(1\lel_i<r_i\le2n\))。保证每条线段的端点为整数,且\(\foralli,j\)(\(i\nej\)),不存在\(l_i=l_j\)或\(r_i=r_j\),不存......
  • P5943 [POI2002] 最大的园地 题解
    题目传送门前置知识单调栈简化题意在一个\(n\timesn\)的正方形内找到最大的由\(0\)组成的子矩形的面积。解法令\(f_{i,j}(1\lei,j\len)\)表示从\((1,j)\)到\((i,j)\)中以\((i,j)\)结尾的均为\(0\)的子串长度,即\((i,j)\)上面可延伸的最大距离(子矩形的......
  • Codeforces 1702G2 题解
    题目大意给出一个大小为\(n\)的树,\(q\)次询问,每次给出一个大小为\(m\)的点集,判断是否有一条链覆盖这些点(这条链可以经过其他点)。\(n,\summ\leqslant2\cdot10^5\),\(q\leqslant10^5\)。提示提示1思考将$m$个点按深度排序。题解题解考虑将\(m\)个点按树......
  • 单源最短路模板
    SPFA#include<bits/stdc++.h>#definerintregisterint#defineendl'\n'usingnamespacestd;constintN=1e5+5;constintM=1e6+5;constintinf=1e9;inth[N],e[M],ne[M],dist[N],w[M];intn,m,s,idx;queue<int>......
  • ABC322G题解
    这场的G怎么这么毒瘤啊/kk听说正解是DP?我爆搜头一个表示不服!statement找出三元组\((S,a,b)\)的数量,使得\(S\)在\(a\)进制下和在\(b\)进制下的差为\(X\),其中\(0\leqS_i<(min(a,b,10))\)。首先因为\(X>0\)显然\(S\)不可能为\(1\)位数。如果\(S\)......