NOIP2017 Day1 T3 逛公园(最短路+拓扑排序+DP)
神tm比赛时多清个零就有60了T T
首先跑出1起点和n起点的最短路,因为k只有50,所以可以DP。设f[i][j]表示比最短路多走i的长度,到j的方案数。
我们发现如果在最短路上的和零边会有后向性,怎么办呢?拓扑排序。
把最短路上的点和零边的点拉出来跑拓扑排序,如果有零环的话必定度数不为0,而且要注意零环必须在<=最短路+k的路径上才输出-1,这个就用刚刚跑出来的1起点到n起点的最短路来判断就好了。
然后先按拓扑序DP出i相同的,然后再DP不在最短路上或者零边的。
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<queue>
#define MOD(x) ((x)>=mod?(x)-mod:(x))
using namespace std;
const int maxn=;
struct tjm{int too, dis, pre;}e[][maxn];
struct poi{int x, dis;};
priority_queue<poi>q;
bool operator<(poi a, poi b){return a.dis>b.dis;}
int T, x, y, z, n, m, K, mod, top, tot[], ans;
int f[][maxn], dist[][maxn], last[][maxn], d[maxn], st[maxn];
void read(int &k)
{
int f=; k=; char c=getchar();
while(c<'' || c>'') c=='-' && (f=-), c=getchar();
while(c<='' && c>='') k=k*+c-'', c=getchar();
k*=f;
}
inline void add(int x, int y, int z, int ty){e[ty][++tot[ty]]=(tjm){y, z, last[ty][x]}; last[ty][x]=tot[ty];}
inline void dij(int x, int ty)
{
memset(dist[ty], , sizeof(dist[ty]));
dist[ty][x]=; q.push((poi){x, });
while(!q.empty())
{
poi now=q.top(); q.pop();
if(dist[ty][now.x]!=now.dis) continue;
for(int i=last[ty][now.x], too;i;i=e[ty][i].pre)
if(dist[ty][too=e[ty][i].too]>dist[ty][now.x]+e[ty][i].dis)
{
dist[ty][too]=dist[ty][now.x]+e[ty][i].dis;
q.push((poi){too, dist[ty][too]});
}
}
}
inline bool topo()
{
memset(d, , sizeof(d));
for(int i=;i<=n;i++)
for(int j=last[][i], too;j;j=e[][j].pre)
if(dist[][i]+e[][j].dis==dist[][too=e[][j].too]) d[too]++;
top=; for(int i=;i<=n;i++) if(!d[i]) st[++top]=i;
for(int i=;i<=top;i++)
for(int j=last[][st[i]], too;j;j=e[][j].pre)
if(dist[][st[i]]+e[][j].dis==dist[][too=e[][j].too])
{
d[too]--;
if(!d[too]) st[++top]=too;
}
for(int i=;i<=n;i++) if(d[i] && dist[][i]+dist[i][n]<=dist[][n]+K) return ;
return ;
}
int main()
{
read(T);
while(T--)
{
memset(last, , sizeof(last)); tot[]=tot[]=;
read(n); read(m); read(K); read(mod);
for(int i=;i<=m;i++) read(x), read(y), read(z), add(x, y, z, ), add(y, x, z, );
dij(, ); dij(n, );
if(!topo()) {puts("-1"); continue;}
memset(f, , sizeof(f)); f[][]=; ans=;
for(int i=;i<=K;i++)
{
for(int j=;j<=top;j++)
for(int k=last[][st[j]], too;k;k=e[][k].pre)
if(e[][k].dis+dist[][st[j]]==dist[][too=e[][k].too])
f[i][too]+=f[i][st[j]], f[i][too]=MOD(f[i][too]);
for(int j=;j<=n;j++)
for(int k=last[][j], too, tmp;k;k=e[][k].pre)
if((tmp=i+e[][k].dis+dist[][j]-dist[][too=e[][k].too])<=K && i!=tmp)
f[tmp][too]+=f[i][j], f[tmp][too]=MOD(f[tmp][too]);
ans+=f[i][n]; ans=MOD(ans);
}
printf("%d\n", ans);
}
}
NOIP2017 Day1 T3 逛公园(最短路+拓扑排序+DP)的更多相关文章
- [NOIP2017]逛公园 最短路+拓扑排序+dp
题目描述 给出一张 $n$ 个点 $m$ 条边的有向图,边权为非负整数.求满足路径长度小于等于 $1$ 到 $n$ 最短路 $+k$ 的 $1$ 到 $n$ 的路径条数模 $p$ ,如果有无数条则输出 ...
- [Luogu P3953] 逛公园 (最短路+拓扑排序+DP)
题面 传送门:https://www.luogu.org/problemnew/show/P3953 Solution 这是一道神题 首先,我们不妨想一下K=0,即求最短路方案数的部分分. 我们很容易 ...
- NOIP2017 Day1 T3 逛公园
NOIP2017 Day1 T3 更好的阅读体验 题目描述 策策同学特别喜欢逛公园.公园可以看成一张\(N\)个点\(M\)条边构成的有向图,且没有 自环和重边.其中1号点是公园的入口,\(N\)号点 ...
- 【BZOJ5109】[CodePlus 2017]大吉大利,晚上吃鸡! 最短路+拓扑排序+DP
[BZOJ5109][CodePlus 2017]大吉大利,晚上吃鸡! Description 最近<绝地求生:大逃杀>风靡全球,皮皮和毛毛也迷上了这款游戏,他们经常组队玩这款游戏.在游戏 ...
- 洛谷 3953 NOIP2017提高组Day1 T3 逛公园
[题解] 先建反向图,用dijkstra跑出每个点到n的最短距离dis[i] 设f[u][k]表示dis(u,n)<=mindis(u,n)+k的方案数.对于边e(u,v,w),走了这条边的话需 ...
- Luogu P3953 逛公园(最短路+记忆化搜索)
P3953 逛公园 题面 题目描述 策策同学特别喜欢逛公园.公园可以看成一张 \(N\) 个点 \(M\) 条边构成的有向图,且没有自环和重边.其中 \(1\) 号点是公园的入口,\(N\) 号点是公 ...
- BZOJ_1916_[Usaco2010 Open]冲浪_分层图+拓扑排序+DP
BZOJ_1916_[Usaco2010 Open]冲浪_分层图+拓扑排序+DP Description 受到秘鲁的马丘比丘的新式水上乐园的启发,Farmer John决定也为奶牛们建 一个水上乐园. ...
- POJ 3249 拓扑排序+DP
貌似是道水题.TLE了几次.把所有的输入输出改成scanf 和 printf ,有吧队列改成了数组模拟.然后就AC 了.2333333.... Description: MR.DOG 在找工作的过程中 ...
- 洛谷P3244 落忆枫音 [HNOI2015] 拓扑排序+dp
正解:拓扑排序+dp 解题报告: 传送门 我好暴躁昂,,,怎么感觉HNOI每年总有那么几道题题面巨长啊,,,语文不好真是太心痛辣QAQ 所以还是要简述一下题意,,,就是说,本来是有一个DAG,然后后来 ...
随机推荐
- Keil5的设置
目录 编码格式 字体大小 代码颜色 编码格式 有时候用keil打开工程的时候,发现中文注释是乱码的格式,这是因为编码格式方式不对造成的.可以通过设置不同的编码方式来解决. 点击Edit->Con ...
- PHP双向队列
假定队列的左边为头部,右边为尾部 <?php class myDeque { private $deque=array(); /** *头部进队列 */ public function lPus ...
- 随身Wifi+win7 搭建http代理 域名劫持 抓包 内容篡改实验环境
需求来源: 1.平板或手机是个封闭系统无法给wifi设置代理 2.需要利用filllder进行抓包,内容篡改等实验 拥有硬件资源:PC机器 + 小米随身wifi 方案1: NtBind Dns + N ...
- 3星|李开复《AI·未来》:中国创业公司有独特优势,人工智能可能会加剧社会的不平等与不稳定
主要内容:作者对自己一些经历的回顾,对中美两国人工智能行业的回顾与展望. 作者认为中国的创业公司比美国节奏更快工作更拼命,深圳在硬件创新上远远领先于美国,中国创业公司们走出了一条跟美国不同的路. 作者 ...
- 如何使用phpredis连接Redis的方法
本文跟大家介绍使用同一VPC内弹性云服务器ECS上的phpredis连接Redis的方法. 更多的客户端的使用方法,请参考https://redis.io/clients 前提条件 已成功申请Redi ...
- 学习使用Git 版本控制 代码管理
title: 学习使用Git 版本控制 代码管理 notebook: 经验累积 tags:Git --- Git 版本控制 学习教程 Git版本控制器,可以作为程序员.计算机科学和软件工程的研究人员在 ...
- python request 获取cookies value值的方法
import requests res = requests.get(url) cookies = requests.utils.dict_from_cookiejar(res.cookies) pr ...
- 子元素设置margin-top后,父元素跟随下移的问题
子元素设置margin-top后,父元素跟随下移的问题 <!DOCTYPE html> <html lang="en"> <head> < ...
- .net web 应用程序C#
简介 开发环境:VS2015 ASP.NET:可以开发出几乎所有运行在Windows上的应用程序:.NET是一种架构,一种新的API:引入程序集代替DLL: ADO.NET:一组.NET组件提供对数据 ...
- 阿帕奇web服务器下载部署安装运行
链接: https://jingyan.baidu.com/album/d8072ac47baf0eec95cefdca.html?picindex=4 1.apache服务安装成功可是启动失败“wi ...