题目描述 给出一张 $n$ 个点 $m$ 条边的有向图,边权为非负整数.求满足路径长度小于等于 $1$ 到 $n$ 最短路 $+k$ 的 $1$ 到 $n$ 的路径条数模 $p$ ,如果有无数条则输出 $-1$ . 输入 第一行包含一个整数 $T$ , 代表数据组数. 接下来 $T$ 组数据,对于每组数据: 第一行包含四个整数 $N,M,K,P$ ,每两个整数之间用一个空格隔开. 接下来 $M$ 行,每行三个整数 $a_i,b_i,c_i$ ,代表编号为 $a_i,b_i$ 的点之间有一条权值为…
题面 传送门:https://www.luogu.org/problemnew/show/P3953 Solution 这是一道神题 首先,我们不妨想一下K=0,即求最短路方案数的部分分. 我们很容易可以想到一个做法,就是魔改迪杰斯特拉做法: 如果一个点可以更新到达其他点的距离,那个点的方案数就是这个点的方案数:如果一个点所更新出来的距离和之前的相等,那个点的方案数加等当前点的方案数. 用式子可以表现为: f[j]=f[i] (dis[j]>dis[i]+x)   f[j]+=f[i] (dis…
跑一遍dij根据最短路DAG进行拓扑排序,按拓扑序dp即可.wa了三发感觉非常凉. #include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> #include<queue> using namespace std; #define ll long long #defi…
---题面--- 题解: 挺好的一道题. 首先我们将所有边反向,跑出n到每个点的最短路,然后f[i][j]表示从i号节点出发,路径长比最短路大j的方案数. 观察到,如果图中出现了0环,那么我们可以通过在环上走无数次来获得无数条不同路径,因此这就无解了. 如果没有0环,当且仅当这张图的最短路图是一个DAG(可以画图思考一下),因为如果没有0环,而最短路图中出现了环,那么意味着你可以无数次以最短路到达同一个点,而不增加路径长,这显然是不可能的,同理,如果有0环,那么最短路图中就会出现环. 因此我们判…
题目链接 Solution 我只会60分暴力... 正解是 DP. 状态定义: \(f[i][j]\) 代表 \(1\) 到 \(i\) 比最短路长 \(j\) 的方案数. 那么很显然最后答案也就是 \(\sum^{i=0}_{k}f[n][i]\). 转移方程: 对于任一状态 \(f[i][j]\) 我们对可以到达它的点 \(v\) 进行讨论: \(v\) 本身为 \(1\) 到 \(i\) 的最短路上的节点,则此时 \[f[i][j]+=f[v][j]\] 若 \(v\) 并非到其最短路上的…
先跑一边dijkstra算出从1到i的最短距离dis[i] 然后建反向边 从n开始记忆化搜索,(p,k)表示1到p的距离=dis[p]+k的方案数 答案就是$\sum\limits_{i=0}^{k}{(n,i)}$ 考虑0环,如果我记搜的时候搜到了0环,那答案就是-1,可以先用tarjan处理一下0边 看看有哪些点在零环上 (其实也可以开个栈 做到(p,k)的时候看(p,k)是不是已经在栈中了 如果是那就是-1) #include<bits/stdc++.h> #define CLR(a,x…
[题解]NOIP2017逛公园(DP) 第一次交挂了27分...我是不是必将惨败了... 考虑这样一种做法,设\(d_i\)表示从该节点到n​节点的最短路径,\(dp(i,k)\)表示从\(i\)节点到\(n\)多走至多\(k\)距离的方案数.转移相当于枚举走哪条边,状态的变化是如果走这条边会比最短路多多少. 转移方程 \[ dp(i,k) =\sum_{(i,u,w)\in E} dp(u,k-(w-(d_i-d_u)) \] 直接用dfs实现转移(记得判环)即可. ... ... ... 但…
考试的时候灵光一闪,瞬间推出DP方程,但是不知道怎么判-1,然后?然后就炸了. 后来发现,我只要把拓扑和DP分开,中间加一个判断,就AC了,可惜. 看这道题,我们首先来想有哪些情况是-1:只要有零环在满足题目要求的路径上,那么这条路径就可以不停地走,于是就-1了. 如何判有没有零环呢? 机械化地两遍不同方向的SPFA,就知道某个点在不在最短路上,以此建一个最短路图,在最短路图上找零环.于是就拓扑啦.稍加判断就解决了整个题目最关键的-1. 接下来就是DP了,设f[i][j]表示走到i点,走过路程已…
[NOIP2017] 逛公园 题目大意: 给定一张图,询问长度 不超过1到n的最短路长度加k 的1到n的路径 有多少条. 数据范围: 点数\(n \le 10^5\) ,边数\(m \le 2*10^5\) 题目解法 两个月后再看也不是太难,自己就能独立思考出来. 首先是判-1的问题,显然能产生-1的只有0环. 所以把0环都找出来, 然后检查一下\(dis[\)\(1\),环\(]\) + \(dis[\)环,\(n]\) 是否小于等于 \(dis[1,n]+K\)即可. 如果不是无限路径的话,…
神tm比赛时多清个零就有60了T T 首先跑出1起点和n起点的最短路,因为k只有50,所以可以DP.设f[i][j]表示比最短路多走i的长度,到j的方案数. 我们发现如果在最短路上的和零边会有后向性,怎么办呢?拓扑排序. 把最短路上的点和零边的点拉出来跑拓扑排序,如果有零环的话必定度数不为0,而且要注意零环必须在<=最短路+k的路径上才输出-1,这个就用刚刚跑出来的1起点到n起点的最短路来判断就好了. 然后先按拓扑序DP出i相同的,然后再DP不在最短路上或者零边的. #include<iost…