noip2017逛公园
题解:
之前知道正解并没有写过。。
#include <bits/stdc++.h>
using namespace std;
#define rint register int
#define IL inline
#define rep(i,h,t) for (int i=h;i<=t;i++)
#define dep(i,t,h) for (int i=t;i>=h;i--)
#define me(x) memset(x,0,sizeof(x))
char ss[<<],*A=ss,*B=ss;
IL char gc()
{
return A==B&&(B=(A=ss)+fread(ss,,<<,stdin),A==B)?EOF:*A++;
}
template<class T>void read(T &x)
{
rint f=,c; while (c=gc(),c<||c>) if (c=='-') f=-; x=(c^);
while (c=gc(),c>&&c<) x=(x<<)+(x<<)+(c^); x*=f;
}
const int N=3e5;
struct re{
int a,b,c;
}e[N],jl[N];
int n,m,k,p,head[N],l,rd[N],tim[N];
void arr(int x,int y,int z)
{
e[++l].a=head[x];
e[l].b=y;
e[l].c=z;
head[x]=l;
}
queue<int> q;
stack<int> S;
int dfn[N],low[N],col[N],color_cnt,sz[N],cnt,tim2[N];
bool ins[N];
void tarjan(int x,int y)
{
dfn[x]=low[x]=++cnt; S.push(x); ins[x]=;
for (rint u=head[x];u;u=e[u].a)
{
rint v=e[u].b;
if (!dfn[v])
{
tarjan(v,x);
dfn[x]=min(dfn[x],low[v]);
}
if (ins[v]) dfn[x]=min(dfn[x],dfn[v]);
}
if (dfn[x]==low[x])
{
color_cnt++;
while ()
{
int y=S.top(); S.pop(); col[y]=color_cnt; ins[y]=; sz[color_cnt]++;
if (y==x) break;
}
}
}
const int INF=5e8;
int dis[N],dis1[N],dis2[N];
struct cmp{
bool operator () (re x,re y)
{
return x.b>y.b;
}
};
priority_queue<re,vector<re>,cmp> Q;
bool vis[N];
void dij(int x)
{
me(vis);
rep(i,,n) dis[i]=INF;
Q.push((re){x,}); dis[x]=;
while (!Q.empty())
{
int x=Q.top().a; Q.pop();
if (vis[x]) continue; vis[x]=;
for (rint u=head[x];u;u=e[u].a)
{
int v=e[u].b;
if (dis[v]>dis[x]+e[u].c)
{
dis[v]=dis[x]+e[u].c;
Q.push((re){v,dis[v]});
}
}
}
}
int f[N][];
const int N2=1.5e7;
re ve[N2];
IL void js(int &x,int y)
{
x=(x+y)%p;
}
bool cmp3(re y,re x)
{
int jl1=dis1[x.a]+x.b;
int jl2=dis1[y.a]+y.b;
return (jl2<jl1)||(jl1==jl2&&tim[y.a]<tim[x.a]);
}
int main()
{
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
int T;
read(T);
rep(ttt,,T)
{
l=; me(head); me(dfn); me(low); me(sz); color_cnt=;
read(n); read(m); read(k); read(p); me(rd);
rep(i,,m)
{
int x,y,z;
read(x); read(y); read(z);
jl[i]=(re){x,y,z};
if (z==) arr(x,y,z),rd[y]++;
}
rep(i,,n) if (!rd[i]) q.push(i);
int cnt=;
while (!q.empty())
{
int x=q.front(); q.pop(); tim[x]=++cnt;
for (rint u=head[x];u;u=e[u].a)
{
rint v=e[u].b;
rd[v]--;
if (!rd[v]) q.push(v);
}
}
rep(i,,n) if (!dfn[i]) tarjan(i,);
me(head); l=;
int s=col[],t=col[n];
rep(i,,m)
if (col[jl[i].a]!=col[jl[i].b]) arr(col[jl[i].a],col[jl[i].b],jl[i].c);
dij(s);
rep(i,,n) dis1[i]=dis[i];
me(head); l=;
rep(i,,m)
if (col[jl[i].a]!=col[jl[i].b]) arr(col[jl[i].b],col[jl[i].a],jl[i].c);
dij(t);
rep(i,,n) dis2[i]=dis[i];
int now=dis1[n];
bool tt=;
rep(i,,color_cnt)
if (dis1[i]+dis2[i]<=now+k&&sz[i]>) tt=;
if (tt)
{
cout<<-<<endl;
continue;
}
me(head); l=;
rep(i,,m)
if (col[jl[i].a]!=col[jl[i].b]) arr(col[jl[i].a],col[jl[i].b],jl[i].c);
int ans=;
me(f);
f[s][]=;
rep(i,,n) tim2[col[i]]=tim[i];
rep(i,,n) tim[i]=tim2[i];
int cnt2=;
rep(i,,color_cnt)
rep(j,,)
if (dis1[i]+dis2[i]+j<=now+k)
{
ve[++cnt2]=(re){i,j};
}
sort(ve+,ve+cnt2+,cmp3);
rep(i,,cnt2)
{
re xx=ve[i];
int x=xx.a,y=xx.b;
if (!f[x][y]) continue;
if (x==t) ans=(ans+f[x][y])%p;
for (rint u=head[x];u;u=e[u].a)
{
rint v=e[u].b;
if (e[u].c+y+dis1[x]+dis2[v]<=now+k)
{
int t1=f[v][e[u].c+y+dis1[x]-dis1[v]],t2=f[x][y];
js(t1,t2);
f[v][e[u].c+y+dis1[x]-dis1[v]]=t1;
}
}
}
cout<<ans<<endl;
}
return ;
}
我觉得这细节真的挺多的。。
而且我都不知道我去年怎么写的60分了。。
网上的方法好像比我的简单。。。
首先在0环上我的处理是
先缩点,然后判缩完后的点能否在路径上
如果能在,输出-1
由于这个缩点还是带来了比较大的干扰。。
调试中的几个错都是这个产生的。。
另外最短路据说是线段树优化跑的最快??
最后的dp还是比较简单的
f[i][j]表示到i点,比原先最短路长j,然后对终点跑一遍最短路来剪枝
然后发现相同dis可以互相转移
所以根据零边拓扑排序一下
网上的判0环的方法比较简单
直接在做的时候 如果扩展到之前的状态 就说明有0环
这很显然啊。。。。
主要刚开始没仔细想这个过程。。
noip至少得留1:30 才能搞完这题吧。。 2:00就比较稳
诶网上最简单的代码好简单啊。。。
直接对s跑一遍最短路,然后直接dp 省掉所有过程啊 而且还挺快的。。。(看来这个剪枝作用也不是很大)
所以下次还是想清楚再写。。。 看看有没有简单的办法
要是写后面这份代码 1小时足够了啊。。。
noip2017逛公园的更多相关文章
- [NOIP2017] 逛公园
[NOIP2017] 逛公园 题目大意: 给定一张图,询问长度 不超过1到n的最短路长度加k 的1到n的路径 有多少条. 数据范围: 点数\(n \le 10^5\) ,边数\(m \le 2*10^ ...
- 【比赛】NOIP2017 逛公园
考试的时候灵光一闪,瞬间推出DP方程,但是不知道怎么判-1,然后?然后就炸了. 后来发现,我只要把拓扑和DP分开,中间加一个判断,就AC了,可惜. 看这道题,我们首先来想有哪些情况是-1:只要有零环在 ...
- 【题解】NOIP2017逛公园(DP)
[题解]NOIP2017逛公园(DP) 第一次交挂了27分...我是不是必将惨败了... 考虑这样一种做法,设\(d_i\)表示从该节点到n节点的最短路径,\(dp(i,k)\)表示从\(i\)节点 ...
- NOIP2017逛公园(dp+最短路)
策策同学特别喜欢逛公园.公园可以看成一张N个点M条边构成的有向图,且没有 自环和重边.其中1号点是公园的入口,N号点是公园的出口,每条边有一个非负权值, 代表策策经过这条边所要花的时间. 策策每天都会 ...
- NOIP2017 逛公园 题解报告 【最短路 + 拓扑序 + dp】
题目描述 策策同学特别喜欢逛公园.公园可以看成一张NNN个点MMM条边构成的有向图,且没有 自环和重边.其中1号点是公园的入口,NNN号点是公园的出口,每条边有一个非负权值, 代表策策经过这条边所要花 ...
- [NOIP2017]逛公园 题解
我连D1T3都不会我联赛完蛋了 题目描述 策策同学特别喜欢逛公园.公园可以看成一张 N 个点 M 条边构成的有向图,且没有 自环和重边.其中1号点是公园的入口, N 号点是公园的出口,每条边有一个非负 ...
- [NOIP2017] 逛公园 解题报告(DP)
我很不想说 在我的AC代码上我打了表,但实在没有办法了.莫名的8,9个点RE.然而即便是打表...也花了我很久. 这大概是NOIP2017最难的题了,为了让不懂的人更容易理解,这篇题解会比较详细 我的 ...
- [NOIP2017] 逛公园 【最短路】【强连通分量】
题目分析: 首先考虑无数条的情况.出现这种情况一定是一条合法路径经过了$ 0 $环中的点.那么预先判出$ 0 $环中的点和其与$ 1 $和$ n $的距离.加起来若离最短路径不超过$ k $则输出$ ...
- luogu3953 [NOIp2017]逛公园 (tarjan+dijkstra+记忆化搜索)
先跑一边dijkstra算出从1到i的最短距离dis[i] 然后建反向边 从n开始记忆化搜索,(p,k)表示1到p的距离=dis[p]+k的方案数 答案就是$\sum\limits_{i=0}^{k} ...
随机推荐
- 虚拟化之kvm --(vnc控制台)
作者:邓聪聪 随着日益不同的需求增多,为了满足主机供求,get到这一招虚拟化技术,以增加点见识! 1.使用yum安装: yum -y install qemu-kvm libvirt python-v ...
- 【转】gcc中的-w -W和-Wall选项
-w的意思是关闭编译时的警告,也就是编译后不显示任何warning,因为有时在编译之后编译器会显示一些例如数据转换之类的警告,这些警告是我们平时可以忽略的. -Wall选项意思是编译后显示所有警告. ...
- 统一门户与业务系统的sso整合技术方案(单点登录)
一.单点登录(SSO,Single Sign On)整合目前计划接入统一门户的所有业务系统均为基于JavaEE技术的B/S架构系统.由于统一门户的单点登录技术选用的是JA-SIG组织开发的Cas Se ...
- socket 通信 error:88
调用函数(setsockopt)来设置 recv buffer 和send buffer时报错: setsockopt error: Socket operation on non-socket(e ...
- ES--03
第二十一讲! 1.上机动手实战演练基于_version进行乐观锁并发控制 (1)先构造一条数据出来 PUT /test_index/test_type/7{ "test_field" ...
- 海康JAVA SDK库动态路径加载
海康JAVA SDK初始化路径默认是放在classes下面,见下: HCNetSDK INSTANCE = (HCNetSDK) Native.loadLibrary("HCNetSDK&q ...
- Linux中给普通用户添加sudo权限
使用Linux系统时,经常会被要求使用超级权限,但是root的权限太过大了,一般慎用!!!因此可以通过给普通用户添加sudo权限,平常用普通用户进行操作,当需要root权限的时候进行sudo操作.以下 ...
- [HTTP]Etag的工作流程
1. 浏览器首次访问该资源时,web服务器返回资源的同时,响应报文头携带ETag标签: 2. 浏览器将保存该Etag标签的值: 3. 当浏览器发起下一次请求,请求报文头将会携带 If-None-Mat ...
- python-进程池与线程池,协程
一.进程池与线程池 实现并发的手段有两种,多线程和多进程.注:并发是指多个任务看起来是同时运行的.主要是切换+保存状态. 当我们需要执行的并发任务大于cpu的核数时,我们需要知道一个操作系统不能无限的 ...
- MongoDB、Hbase、Redis等NoSQL优劣势、应用场景
NoSQL的四大种类 NoSQL数据库在整个数据库领域的江湖地位已经不言而喻.在大数据时代,虽然RDBMS很优秀,但是面对快速增长的数据规模和日渐复杂的数据模型,RDBMS渐渐力不从心,无法应对很多数 ...