park作为今年noipday1最后一道题还是相比前面几道题还是有点难度的

首先你可以思考一下,第一天dp不见了,再看一下这题,有向图,看起来就比较像一个dp,考虑dp方程,首先肯定有一维是到哪个节点,还有一维肯定与路径长度有关,显然第二位就记录超过最短路多少。

这样我们可以找到dp方程,首先枚举一个kk(0<=kk<=k),按拓扑序枚举每一个点,枚举以这个点为起点的路径,如果这条路在最短路上,那么dp[v][kk]+=dp[u][kk],else 如果dis[u]+kk+路径长度<=dis[v]+k则也可以进行类似的转移

首先我们先正着跑一遍spfa,再反着跑一遍,以为要判断一个点在不在最短路上,只需要看起点到它的最短路+终点到它的最短路之和是否等于起点到终点的最短路

接下来如果这条边在最短路上则这条路终点入度+1,再拓扑排序一遍顺便检查出有无0环,接下来就可以dp了

接下来看代码吧

#include<bits/stdc++.h>
using namespace std;
typedef int sign;
typedef long long ll;
#define For(i,a,b) for(register sign i=(sign)a;i<=(sign)b;++i)
#define Fordown(i,a,b) for(register sign i=(sign)a;i>=(sign)b;--i)
const int N=1e5+5;
bool cmax(sign &a,sign b){return a<b?a=b,1:0;}
bool cmin(sign &a,sign b){return a>b?a=b,1:0;}
template<typename T>T read()
{
T ans=0,f=1;
char ch=getchar();
while(!isdigit(ch)&&ch!='-')ch=getchar();
if(ch=='-')f=-1,ch=getchar();
while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch-'0'),ch=getchar();
return ans*f;
}
void file()
{
#ifndef ONLINE_JUDGE
freopen("park.in","r",stdin);
freopen("park.out","w",stdout);
#endif
}
int dis[N][2],in[N];
int n,m,k,p;
struct graph
{
int head[N],tt,nex[N<<1],w[N<<1],to[N<<1];
inline void init()
{
tt=0;
For(i,1,n)head[i]=0;
}
inline void add(int x,int y,int z)
{
++tt;
w[tt]=z;to[tt]=y;
nex[tt]=head[x];head[x]=tt;
}
}G[2];//因为双向建图,所以写在结构体里
#define tra(G,i,u) for(register int i=G.head[u];i;i=G.nex[i])
bool vis[N];
inline void input()
{
int x,y,z;
n=read<int>();m=read<int>();k=read<int>();p=read<int>();
G[0].init();G[1].init();
For(i,1,m)
{
x=read<int>();y=read<int>();z=read<int>();
G[0].add(x,y,z);G[1].add(y,x,z);
}
}
queue<int>q;
inline void spfa(int st,int now)
{
q.push(st);
dis[st][now]=0;
int u,v;
while(!q.empty())
{
u=q.front();q.pop();
vis[u]=0;
tra(G[now],i,u)
{
v=G[now].to[i];
if(cmin(dis[v][now],dis[u][now]+G[now].w[i]))
{
if(!vis[v])
{
vis[v]=1;
//if(!q.empty()&&dis[v]<=dis[q.front()])q.push_front(v);
q.push(v);
}
}
}
}
}//跑spfa,因为要跑两遍,所以0表示正着的,1表示反着的
int l[N];
bool check()
{
int v,u;
For(i,1,n)if(!in[i])l[++l[0]]=i;//入度为零入队
For(j,1,l[0])
{
u=l[j];
tra(G[0],i,u)
{
v=G[0].to[i];
if(dis[v][0]==dis[u][0]+G[0].w[i])
{
//在最短路上就入度-1
--in[v];
if(!in[v])l[++l[0]]=v;
}
}
}
For(i,1,n)if(in[i]&&dis[i][0]+dis[i][1]<=dis[n][0]+k)return 1;
//如果在最短路上且有环,则说明有0环
return 0;
}
int dp[N][55];
inline void add(int &a,int b)
{
a+=b;
if(a>p)a-=p;
}
inline void topsort()
{
int v,u;
dp[1][0]=1;
For(kk,0,k)
{
For(j,1,l[0])
{
u=l[j];
tra(G[0],i,u)
{
v=G[0].to[i];
if(dis[v][0]==dis[u][0]+G[0].w[i])add(dp[v][kk],dp[u][kk]);//如果在最短路上,则沿着最短路走下去,当前比最短路大kk,则走到终点也一定比最短路大kk
else if(kk+dis[u][0]+G[0].w[i]<=dis[v][0]+k)
{
add(dp[v][kk+dis[u][0]+G[0].w[i]-dis[v][0]],dp[u][kk]);//走过这条路,当前比最短路大kk,则走过这条路后,又长了dis[u][0]+G[0].w[i]-dis[v][0]]
}
}
}
}
int ans=0;
For(i,0,k)add(ans,dp[n][i]);
printf("%d\n",ans);
}
inline void work()
{
spfa(1,0);
spfa(n,1);
int v;l[0]=0;
For(u,1,n)
{
tra(G[0],i,u)
{
v=G[0].to[i];
if(dis[v][0]==dis[u][0]+G[0].w[i])in[v]++;//入度
}
}
if(check())
{
puts("-1");
return;
}
topsort();
}
const int inf=0x3f3f3f3f;
inline void init()
{
For(i,1,n)For(j,0,1)dis[i][j]=inf;
For(i,1,n)in[i]=0;
For(i,1,n)For(j,0,k)dp[i][j]=0;
//初始化,写memset,在洛谷一直re
}
int main()
{
//从main函数看起是个好习惯
file();
int T=read<int>();
while(T--)
{
input();
init();
work();
}
return 0;
}

NOIP2017逛公园(park)解题报告的更多相关文章

  1. 【比赛】NOIP2017 逛公园

    考试的时候灵光一闪,瞬间推出DP方程,但是不知道怎么判-1,然后?然后就炸了. 后来发现,我只要把拓扑和DP分开,中间加一个判断,就AC了,可惜. 看这道题,我们首先来想有哪些情况是-1:只要有零环在 ...

  2. [NOIP2017] 逛公园

    [NOIP2017] 逛公园 题目大意: 给定一张图,询问长度 不超过1到n的最短路长度加k 的1到n的路径 有多少条. 数据范围: 点数\(n \le 10^5\) ,边数\(m \le 2*10^ ...

  3. 【题解】NOIP2017逛公园(DP)

    [题解]NOIP2017逛公园(DP) 第一次交挂了27分...我是不是必将惨败了... 考虑这样一种做法,设\(d_i\)表示从该节点到n​节点的最短路径,\(dp(i,k)\)表示从\(i\)节点 ...

  4. NOIP2017 逛公园 题解报告 【最短路 + 拓扑序 + dp】

    题目描述 策策同学特别喜欢逛公园.公园可以看成一张NNN个点MMM条边构成的有向图,且没有 自环和重边.其中1号点是公园的入口,NNN号点是公园的出口,每条边有一个非负权值, 代表策策经过这条边所要花 ...

  5. NOIP2017逛公园(dp+最短路)

    策策同学特别喜欢逛公园.公园可以看成一张N个点M条边构成的有向图,且没有 自环和重边.其中1号点是公园的入口,N号点是公园的出口,每条边有一个非负权值, 代表策策经过这条边所要花的时间. 策策每天都会 ...

  6. 冲刺Noip2017模拟赛5 解题报告——五十岚芒果酱

    1. 公约数(gcd) [问题描述] 给定一个正整数,在[,n]的范围内,求出有多少个无序数对(a,b)满足 gcd(a,b)=a xor b. [输入格式] 输入共一行,一个正整数n. [输出格式] ...

  7. 冲刺Noip2017模拟赛3 解题报告——五十岚芒果酱

    题1  素数 [问题描述] 给定一个正整数N,询问1到N中有多少个素数. [输入格式]primenum.in 一个正整数N. [输出格式]primenum.out 一个数Ans,表示1到N中有多少个素 ...

  8. 冲刺Noip2017模拟赛2 解题报告——五十岚芒果酱

    题1 牛跑步(running) [题目描述] 新牛到部队,CG 要求它们每天早上搞晨跑,从 A 农场跑到 B 农场.从 A 农场到 B 农场中有 n- 个路口,分别标上号,A 农场为 号,B 农场为 ...

  9. 冲刺Noip2017模拟赛1 解题报告——五十岚芒果酱

    题1 国际象棋(chess) [问题描述] 有N个人要参加国际象棋比赛,该比赛要进行K场对弈.每个人最多参加2场对弈,最少参加0场对弈.每个人都有一个与其他人都不相同的等级(用一个正整数来表示).在对 ...

  10. [NOIP2017]逛公园 题解

    我连D1T3都不会我联赛完蛋了 题目描述 策策同学特别喜欢逛公园.公园可以看成一张 N 个点 M 条边构成的有向图,且没有 自环和重边.其中1号点是公园的入口, N 号点是公园的出口,每条边有一个非负 ...

随机推荐

  1. 2017-2018-2 20155204《网络对抗技术》EXP5 MSF基础应用

    一.基础问题回答 用自己的话解释什么是exploit,payload,encode exploit:利用靶机系统中的一些漏洞进行攻击的过程,除去前期准备的工作,这一步是实施攻击. payload:载荷 ...

  2. 2017-2018-1 20155232 嵌入式C语言——时钟

    2017-2018-1 20155232 嵌入式C语言--时钟 任务: 在作业本上完成附图作业,要认真看题目要求. 提交作业截图 作弊本学期成绩清零(有雷同的,不管是给别人传答案,还是找别人要答案都清 ...

  3. 20155308《网络对抗》Exp6 信息搜集与漏洞扫描

    20155308<网络对抗>Exp6 信息搜集与漏洞扫描 原理与实践说明 实践内容 本实践的目标是掌握信息搜集的最基础技能.具体有: 各种搜索技巧的应用 DNS IP注册信息的查询 基本的 ...

  4. 20155323刘威良《网络对抗》Exp4 恶意代码分析

    20155323刘威良<网络对抗>Exp4 恶意代码分析 实践目标 1是监控你自己系统的运行状态,看有没有可疑的程序在运行. 2是分析一个恶意软件,就分析Exp2或Exp3中生成后门软件: ...

  5. Kubernetes学习之路目录

    Kubernetes基础篇 环境说明 版本说明 系统环境 Centos 7.2 Kubernetes版本 v1.11.2 Docker版本 v18.09 Kubernetes学习之路(一)之概念和架构 ...

  6. windows系统中Dotnet core runtime 安装后,无法启动次程序,因为计算机中丢失api-ms-win-crt-runtime-l1-1-0.dll的解决方法

    因为dotnet core runtime依赖vc++2015,如果系统未安装vc++2015则会报上面的错误 解决方案:先下载安装vc++2015再安装dotnet core runtime, vc ...

  7. libgdx学习记录7——Ui

    libgdx中的UI设计主要通过其对应的Style类进行实现,也可以通过skin实现.如果没有编辑好的skin文件,可以创建一个默认的skin,再添加已经设计好的style类即可,然后在需要使用的地方 ...

  8. maven mvn package 打包项目时,出现错误导致失败的解决方法

    解决思路:看报错时在maven打包过程中的哪一步,然后看报错内容,解决报错内容即可,如果是实在不好解决的部分,看看能不能设置不检测,能打包出来就行. 这里是因为mybatis逆向工程插件出现异常所以中 ...

  9. 【ORACLE】oracle11g dg搭建

    --------------------------------每个节点和DG------------------------------------------------------------- ...

  10. Istio 流量治理功能原理与实战

    一.负载均衡算法原理与实战 负载均衡算法(load balancing algorithm),定义了几种基本的流量分发方式,在Istio中共有4种标准负载均衡算法. •Round_Robin: 轮询算 ...