两遍 spfa 然后建立分层图拓扑排序 dp 一下。

写得很差劲。效率很低。

时间复杂度 \(\mathrm{O}(Tnk)\)。

参见这里秒懂。

  1. #include <iostream>
  2. #include <cstring>
  3. #include <cstdio>
  4. #include <queue>
  5. using namespace std;
  6. int T, n, m, k, p, cnt[2], hea[2][100005], dis[2][100005], uu, vv, ww, he[5100005], cn, dp[5100005];
  7. int ind[5100005], f[100005][55];
  8. bool vis[5100005];
  9. queue<int> d;
  10. struct Edge{
  11. int too, nxt, val;
  12. }edge[2][200005], edg[10200005];
  13. void rn(int &x){
  14. char ch=getchar();
  15. x = 0;
  16. while(ch<'0' || ch>'9') ch = getchar();
  17. while(ch>='0' && ch<='9'){
  18. x = x * 10 + ch - '0';
  19. ch = getchar();
  20. }
  21. }
  22. void add_edge(int rr, int fro, int too, int val){
  23. edge[rr][++cnt[rr]].nxt = hea[rr][fro];
  24. edge[rr][cnt[rr]].too = too;
  25. edge[rr][cnt[rr]].val = val;
  26. hea[rr][fro] = cnt[rr];
  27. }
  28. void add_edg(int fro, int too){
  29. edg[++cn].nxt = he[fro];
  30. edg[cn].too = too;
  31. he[fro] = cn;
  32. }
  33. void init(){
  34. rn(n); rn(m); rn(k); rn(p);
  35. memset(he, 0, sizeof(he));
  36. memset(dp, 0, sizeof(dp));
  37. memset(hea, 0, sizeof(hea));
  38. memset(vis, 0, sizeof(vis));
  39. memset(ind, 0, sizeof(ind));
  40. memset(dis, 0x3f, sizeof(dis));
  41. dis[0][1] = dis[1][n] = cnt[0] = cnt[1] = cn = 0;
  42. dp[1] = 1;
  43. for(int i=1; i<=m; i++){
  44. rn(uu); rn(vv); rn(ww);
  45. add_edge(0, uu, vv, ww);
  46. add_edge(1, vv, uu, ww);
  47. }
  48. int qwq=0;
  49. for(int i=1; i<=n; i++)
  50. for(int j=0; j<=k; j++)
  51. f[i][j] = ++qwq;
  52. }
  53. void spfa(int rr){
  54. d.push(rr?n:1);
  55. vis[rr?n:1] = true;
  56. while(!d.empty()){
  57. int x=d.front();
  58. d.pop();
  59. vis[x] = false;
  60. for(int i=hea[rr][x]; i; i=edge[rr][i].nxt){
  61. int t=edge[rr][i].too;
  62. if(dis[rr][t]>dis[rr][x]+edge[rr][i].val){
  63. dis[rr][t] = dis[rr][x] + edge[rr][i].val;
  64. if(!vis[t]){
  65. vis[t] = true;
  66. d.push(t);
  67. }
  68. }
  69. }
  70. }
  71. }
  72. void build(){
  73. for(int i=1; i<=n; i++)
  74. for(int j=0; j<=k; j++)
  75. if(dis[0][i]+dis[1][i]+j<=dis[0][n]+k)
  76. vis[f[i][j]] = true;
  77. for(int i=1; i<=n; i++)
  78. for(int j=0; j<=k; j++)
  79. if(vis[f[i][j]])
  80. for(int l=hea[0][i]; l; l=edge[0][l].nxt){
  81. int t=edge[0][l].too, v=j+dis[0][i]+edge[0][l].val-dis[0][t];
  82. if(v<=k && f[t][v]){
  83. add_edg(f[i][j], f[t][v]);
  84. ind[f[t][v]]++;
  85. }
  86. }
  87. }
  88. void topsort(){
  89. for(int i=1; i<=n; i++)
  90. for(int j=0; j<=k; j++)
  91. if(vis[f[i][j]] && !ind[f[i][j]])
  92. d.push(f[i][j]);
  93. while(!d.empty()){
  94. int x=d.front();
  95. d.pop();
  96. for(int i=he[x]; i; i=edg[i].nxt){
  97. int t=edg[i].too;
  98. ind[t]--;
  99. if(ind[t]==0) d.push(t);
  100. dp[t] = dp[t]+dp[x]>=p?dp[t]+dp[x]-p:dp[t]+dp[x];
  101. }
  102. }
  103. }
  104. int chk(){
  105. for(int i=1; i<=f[n][k]; i++)
  106. if(ind[i]!=0)
  107. return -1;
  108. int re=0;
  109. for(int i=0; i<=k; i++)
  110. re = re+dp[f[n][i]]>=p?re+dp[f[n][i]]-p:re+dp[f[n][i]];
  111. return re;
  112. }
  113. int main(){
  114. cin>>T;
  115. while(T--){
  116. init();
  117. spfa(0);
  118. spfa(1);
  119. build();
  120. topsort();
  121. printf("%d\n", chk());
  122. }
  123. return 0;
  124. }

luogu3563 逛公园的更多相关文章

  1. [vijos P1083] 小白逛公园

    不知怎地竟有种错觉此题最近做过= =目测是类似的?那道题貌似是纯动归? 本来今晚想做两道题的,一道是本题,一道是P1653疯狂的方格取数或NOI08 Employee,看看现在的时间目测这个目标又达不 ...

  2. Bzoj 1756: Vijos1083 小白逛公园 线段树

    1756: Vijos1083 小白逛公园 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1021  Solved: 326[Submit][Statu ...

  3. BZOJ 1756: Vijos1083 小白逛公园

    题目 1756: Vijos1083 小白逛公园 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 856  Solved: 264[Submit][Sta ...

  4. JDOJ-P1260 VIJOS-P1083 小白逛公园

    首先,在这里给大家推荐一个网站,https://neooj.com:8082,这是我母校的网站 言归正传,题目描述 VIJOS-P1083 小白逛公园 Time Limit: 1 Sec  Memor ...

  5. [NOIP2017] 逛公园

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

  6. [NOIp 2017]逛公园

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

  7. 【NOIP 2017】逛公园

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

  8. 逛公园 [NOIP2017 D1T3] [记忆化搜索]

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

  9. [luogu P3953] [noip2017 d1t3] 逛公园

    [luogu P3953] [noip2017 d1t3] 逛公园 题目描述 策策同学特别喜欢逛公园.公园可以看成一张$N$个点$M$条边构成的有向图,且没有 自环和重边.其中1号点是公园的入口,$N ...

随机推荐

  1. Codeforces Round #405 (rated, Div. 2, based on VK Cup 2017 Round 1) A

    Description Bear Limak wants to become the largest of bears, or at least to become larger than his b ...

  2. Codeforces Round #261 (Div. 2) E

    Description Pashmak's homework is a problem about graphs. Although he always tries to do his homewor ...

  3. 洛谷 P3312 [SDOI2014]数表

    式子化出来是$\sum_{T=1}^m{\lfloor}\frac{n}{T}{\rfloor}{\lfloor}\frac{m}{T}{\rfloor}\sum_{k|T}\mu(\frac{T}{ ...

  4. loj124 除数函数求和 1

    loj124 除数函数求和 1 https://loj.ac/problem/124 $\sum_{i=1}^n(\sum_{d|i}d^k)=\sum_{i=1}^n(i^k*{\lfloor}{\ ...

  5. Java三大特性之---封装

    封装从字面上来理解就是包装的意思,专业点就是信息隐藏,是指利用抽象数据类型将数据和基于数据的操作封装在一起,使其构成一个不可分割的独立实体,数据被保护在抽象数据类型的内部,尽可能地隐藏内部的细节,只保 ...

  6. solr facet查询及solrj 读取facet数据[转]

    solr facet查询及solrj 读取facet数据 | 所属分类:solr facet solrj 一.   Facet 简介 Facet 是 solr 的高级搜索功能之一 , 可以给用户提供更 ...

  7. 不能说的hidden

    不能说的hidden 时光跑跑...路在脚下...晨光依在...----Vashon 1.所谓"时尚",本质上就是自己看不见自己的样子.好比我们在地球上,却感觉不到地球在动. 2. ...

  8. 计算1至n的k次方的和

    package com.ywx.count; import java.util.Scanner; /** * @author Vashon * date:20150410 * 题目:计算1至n的k次方 ...

  9. sql server 收缩日志文件

    USE 数据库名称 GO ALTER DATABASE 数据库名称 SET RECOVERY SIMPLE WITH NO_WAIT GO ALTER DATABASE 数据库名称 SET RECOV ...

  10. 语音行业技术领先者Nuance诚招ASR/NLP研发工程师和软件工程师

    Nuance is a leading provider of voice and language solutions for businesses and consumers around the ...