【问题描述】

小P和小R在玩一款益智游戏。游戏在一个正权有向图上进行。

小P控制的角色要从A点走最短路到B点,小R控制的角色要从C点走最短路到D点。

一个玩家每回合可以有两种选择,移动到一个相邻节点或者休息一回合。

假如在某一时刻,小P和小R在相同的节点上,那么可以得到一次特殊奖励,但是在每个节点上最多只能得到一次。

求最多能获得多少次特殊奖励。

【输入格式】

第一行两个整数n,m表示有向图的点数和边数。

接下来m行每行三个整数xi,yi,li,表示从xi到yi有一条长度为li的边。

最后一行四个整数A,B,C,D,描述小P的起终点,小R的起终点。

【输出格式】

输出一个整数表示最多能获得多少次特殊奖励。若小P不能到达B点或者小R不能到达D点则输出-1。

【样例输入输出】

game.in

game.out

5 5

1 2 1

2 3 2

3 4 4

5 2 3

5 3 5

1 3 5 4

2

【数据规模】

对于30%的数据,满足n≤50

对于60%的数据,满足n≤1000,m≤5000

对于100%的数据,满足n≤50000,m≤200000,1≤li≤500000000

【题解】

为了处理出最短路径涉及的块,跑4遍最短路,也就是在原图和反向图上跑最短路对AB和CD各做1次

之后标记两个最短路网的边,被标记两次的就是两个人能相遇的边

对这些被标记的边建一个新图,跑拓扑排序+Dp找DAG的最长路,最长路经即为解

  1. #include <queue>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <algorithm>
  5. #define oo 0x7fffffff - 1
  6. #define max(a, b) ((a) > (b) ? (a) : (b))
  7. using namespace std;
  8. inline int read()
  9. {
  10. int c = getchar(), x = 0;
  11. while(c < '0' || c > '9') c = getchar();
  12. while(c >= '0' && c <= '9') x = (x << 1) + (x << 3) + c - '0', c = getchar();
  13. return x;
  14. }
  15. int ans, n, m, A, B, C, D, cnt, ncnt, fcnt, h[50003], nh[50003], fh[50003], d1[50003], d2[50003], hash[200003], du[50003], Q[50003], f[50003];
  16. struct pt {int v, w, ne;} a[200003], na[200003], fa[200003];
  17. struct ed {int u, v, w;} e[200003];
  18. struct abcd {
  19. int fir, sec;
  20. bool operator < (const abcd oth) const {return sec > oth.sec;} };
  21. priority_queue<abcd> q;
  22. bool mark[50003];
  23. inline void link(int u, int v, int w) {a[++cnt].v = v, a[cnt].w = w, a[cnt].ne = h[u], h[u] = cnt;}
  24. inline void nlink(int u, int v, int w) {na[++ncnt].v = v, na[ncnt].w = w, na[ncnt].ne = nh[u], nh[u] = ncnt;}
  25. inline void flink(int u, int v, int w) {fa[++fcnt].v = v, fa[fcnt].w = w, fa[fcnt].ne = fh[u], fh[u] = fcnt;}
  26. void dijkstra(int x, int d[], pt a[], int h[])
  27. {
  28. for(int i = 1; i <= n; ++i) d[i] = oo, mark[i] = 0;
  29. d[x] = 0; q.push((abcd){x, 0});
  30. while(!q.empty())
  31. {
  32. int now = q.top().fir; q.pop();
  33. if(mark[now]) continue;
  34. mark[now] = 1;
  35. for(int j = h[now]; j; j = a[j].ne)
  36. if(!mark[a[j].v] && d[a[j].v] > d[now] + a[j].w)
  37. {
  38. d[a[j].v] = d[now] + a[j].w;
  39. q.push((abcd){a[j].v, d[a[j].v]});
  40. }
  41. }
  42. }
  43. bool preced()
  44. {
  45. dijkstra(A, d1, a, h);
  46. dijkstra(B, d2, na, nh);
  47. if(d1[B] == oo || d2[A] == oo) return 0;
  48. for(int j = 1; j <= m; ++j) if(d1[e[j].u] + e[j].w + d2[e[j].v] == d1[B]) ++hash[j];
  49. dijkstra(C, d1, a, h);
  50. dijkstra(D, d2, na, nh);
  51. if(d1[D] == oo || d2[C] == oo) return 0;
  52. for(int j = 1; j <= m; ++j)
  53. {
  54. if(d1[e[j].u] + e[j].w + d2[e[j].v] == d1[D]) ++hash[j];
  55. if(hash[j] == 2) {flink(e[j].u, e[j].v, e[j].w); ++du[e[j].v];}
  56. }
  57. return 1;
  58. }
  59. void sortdp()
  60. {
  61. for(int i = 1; i <= n; ++i) {f[i] = 1; if(!du[i]) Q[++Q[0]] = i;}
  62. for(int i = 1; i <= Q[0]; ++i)
  63. {
  64. int now = Q[i];
  65. for(int j = fh[now]; j; j = fa[j].ne)
  66. {
  67. f[fa[j].v] = max(f[fa[j].v], f[now] + 1);
  68. ans = max(ans, f[fa[j].v]);
  69. --du[fa[j].v];
  70. if(!du[fa[j].v]) Q[++Q[0]] = fa[j].v;
  71. }
  72. }
  73. printf("%d\n", ans);
  74. }
  75. int main()
  76. {
  77. freopen("game.in", "r", stdin), freopen("game.out", "w", stdout);
  78. n = read(), m = read();
  79. for(int i = 1; i <= m; ++i)
  80. {
  81. e[i].u = read(), e[i].v = read(), e[i].w = read();
  82. link(e[i].u, e[i].v, e[i].w);
  83. nlink(e[i].v, e[i].u, e[i].w);
  84. }
  85. A = read(), B = read(), C = read(), D = read();
  86. if(preced()) sortdp();
  87. else puts("-1");
  88. fclose(stdin), fclose(stdout);
  89. return 0;
  90. }

  

[第一波模拟\day3\T3]{益智游戏}(game.cpp)的更多相关文章

  1. [第一波模拟\day3\T2]{独立集}(bubble.cpp)

    [问题描述] 有一天,一个名叫顺旺基的程序员从石头里诞生了.又有一天,他学会了冒泡排序和独立集.在一个图里,独立集就是一个点集,满足任意两个点之间没有边.于是他就想把这两个东西结合在一起.众所周知,独 ...

  2. 【2018.06.26NOIP模拟】T3节目parade 【支配树】*

    [2018.06.26NOIP模拟]T3节目parade 题目描述 学校一年一度的学生艺术节开始啦!在这次的艺术节上总共有 N 个节目,并且总共也有 N 个舞台供大家表演.其中第 i 个节目的表演时间 ...

  3. 雅礼 noip2018 模拟赛 day3 T3

    典型树形dp 这里,我们应该看到一些基本性质: ①:如果这个边不能改(不是没有必要改),我们就不改,因为就算改过去还要改回来,显然不是最优的 注意:"不能改"是指边的性质和要求的相 ...

  4. [第一波模拟\day1\T2]{分班}(divide.cpp)

    [题目描述] 小N,小A,小T又大了一岁了. 现在,他们已经是高二年级的学生了.众所周知,高二的小朋友是要进行文理科分班考试的,这样子的话,三个好朋友说不定就会不分在一个班. 于是三个人决定,都考平均 ...

  5. [第一波模拟\day2\T1] {病毒分裂}(split.cpp)

    [题目描述] A 学校的实验室新研制出了一种十分厉害的病毒.由于这种病毒太难以人工制造了,所以专家们在一开始只做出了一个这样的病毒.这个病毒被植入了特殊的微型芯片,使其可以具有一些可编程的特殊性能.最 ...

  6. NOIP欢乐模拟赛 T3 解题报告

    3.小澳的葫芦 (calabash.cpp/c/pas) [题目描述] 小澳最喜欢的歌曲就是<葫芦娃>. 一日表演唱歌,他尽了洪荒之力,唱响心中圣歌. 随之,小澳进入了葫芦世界. 葫芦世界 ...

  7. 20161005 NOIP 模拟赛 T3 解题报告

    subset 3.1 题目描述 一开始你有一个空集,集合可以出现重复元素,然后有 Q 个操作 1. add s 在集合中加入数字 s. 2. del s 在集合中删除数字 s.保证 s 存在 3. c ...

  8. 神奇的Noip模拟试题 T3 科技节 位运算

    3 科技节 (scifest.pas/.c/.cpp) [问题描述] 一年一度的科技节即将到来.同学们报名各项活动的名单交到了方克顺校长那,结果校长一看皱了眉头:这帮学生热情竟然如此高涨,每个人都报那 ...

  9. ztz11的noip模拟赛T3:评分系统

    代码: #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> ...

随机推荐

  1. MySql | 常用操作总结

    创建数据库: CREATE DATABASE 数据库名; 删除数据库名: drop database <数据库名>; 选择数据库: use 数据库名; 创建数据表: CREATE TABL ...

  2. UWP 动画

    一:StoryBoard 一般翻译成演示图版或者故事板,就像电影中的情节串联板,它是一个动画时间线的容器. 二:动画的分类       简单动画:以Animation结尾,例如DoubleAnimat ...

  3. 后缀数组 DC3构造法 —— 详解

    学习了后缀数组,顺便把DC3算法也看了一下,传说中可以O(n)复杂度求出文本串的height,先比较一下倍增算法和DC3算法好辣. DC3 倍增法 时间复杂度 O(n)(但是常数很大)   O(nlo ...

  4. MyBatsi-Mapper映射文件

    Mapper映射文件 cache – 给定命名空间的缓存配置. cache-ref – 其他命名空间缓存配置的引用. resultMap – 是最复杂也是最强大的元素,用来描述如何从数据库结果集中来加 ...

  5. select选择框中,model传的值并非是页面上的值,而是另一个值

    对于编程来说,money和rebate代表的是金额优惠和折扣优惠,采用money或rebate便于数据存储.但是页面显示给用户的时候是金额优惠和折扣优惠,并不是显示编程中所存储数据.所以选择的mode ...

  6. Failure to transfer org.apache.maven.plugins:maven-compiler-plugin:jar:2.5.1

    Mac上写了一段基于Maven的java代码. 上传Git后,在windows上pull下来,eclipse里面各种错误. ArtifactTransferException:Failure to t ...

  7. C# 移动开发(Xamarin.Form) Plugin.BLE 蓝牙连接

    随着Xamarin.Form项目接近尾声,仔细一算才发现过来大半年时间了. 期间除了刚开始有闲情写写,现在总算有空来总结一下了. 来先说 Plugin.BLE (https://github.com/ ...

  8. ABAP和XML数据格式互相转换的两种方式

    ABAP和XML数据格式互相转换是广大开发人员经常遇到的需求.本文介绍两种方式. 1. ABAP提供了一个工具类cl_proxy_xml_transform,通过它的两个方法abap_to_xml_x ...

  9. UGUI世界坐标转换为UI本地坐标

    以下是实现hud跟随3D物体的脚本,只是测试用,不是开发中的代码,脚本挂在任意游戏物体上 demo下载 using UnityEngine; public class SceneFollowUI : ...

  10. 【软件构造】第三章第三节 抽象数据型(ADT)

    第三章第三节 抽象数据型(ADT) 3-1节研究了“数据类型”及其特性 ; 3-2节研究了方法和操作的“规约”及其特性:在本节中,我们将数据和操作复合起来,构成ADT,学习ADT的核心特征,以及如何设 ...