题解

显然要记录每个点来的状态,这样会扩充出点度的平方条边,就gg了

删掉所有的点,把每个边拆成两个点,连一条边权为c

这个时候我们考虑对于原先的每个点,将所有与其相连边所需要的节点(不管是进入还是出去)建一棵虚树,然后用线段树优化建图,优化方法是枚举每个lca,然后将lca的每个子树和其他子树连一条长度为lca深度的边,也就是dfs序上连续的一段

进到这个点的边拆出来的点和负责出去的线段树的子节点连一条边

负责进来的线段树向这个点出去的节点连一条边

跑最短路就行

然后就做完了……

写的我真累= =

我非常好奇到底如何能只写3.xK????

update:貌似有更清奇的写法不用线段树orzzzzz

代码

(7.6K的sd代码,不看也罢)

  1. #include <bits/stdc++.h>
  2. #define fi first
  3. #define se second
  4. #define pii pair<int,int>
  5. #define mp make_pair
  6. #define pb push_back
  7. #define enter putchar('\n')
  8. #define space putchar(' ')
  9. //#define ivorysi
  10. #define MAXN 200005
  11. #define MAXK 80005
  12. typedef long long int64;
  13. using namespace std;
  14. template<class T>
  15. void read(T &res) {
  16. res = 0;char c = getchar();T f = 1;
  17. while(c < '0' || c > '9') {
  18. if(c == '-') f = -1;
  19. c = getchar();
  20. }
  21. while(c >= '0' && c <= '9') {
  22. res = res * 10 + c - '0';
  23. c = getchar();
  24. }
  25. res *= f;
  26. }
  27. template<class T>
  28. void out(T x) {
  29. if(x < 0) {x = -x;putchar('-');}
  30. if(x >= 10) {
  31. out(x / 10);
  32. }
  33. putchar('0' + x % 10);
  34. }
  35. int N,M,K;
  36. priority_queue<pair<int64,int> > Q;
  37. namespace Tree {
  38. struct node {
  39. int next,to;
  40. }E[MAXK * 2];
  41. int head[MAXK],sumE,dfn[MAXK],idx,dep[MAXK];
  42. int st[MAXK * 2][17],len[MAXK * 2],pos[MAXK],tot;
  43. void add(int u,int v) {
  44. E[++sumE].next = head[u];
  45. E[sumE].to = v;
  46. head[u] = sumE;
  47. }
  48. int min_dep(int a,int b) {
  49. return dep[a] < dep[b] ? a : b;
  50. }
  51. int lca(int a,int b) {
  52. a = pos[a];b = pos[b];
  53. if(a > b) swap(a,b);
  54. int l = len[b - a + 1];
  55. return min_dep(st[a][l],st[b - (1 << l) + 1][l]);
  56. }
  57. void dfs(int u,int fa) {
  58. dfn[u] = ++idx;
  59. st[++tot][0] = u;pos[u] = tot;dep[u] = dep[fa] + 1;
  60. for(int i = head[u] ; i ; i = E[i].next) {
  61. int v = E[i].to;
  62. if(v != fa) {
  63. dfs(v,u);
  64. st[++tot][0] = u;
  65. }
  66. }
  67. }
  68. void Init() {
  69. sumE = 0;memset(head,0,sizeof(head));idx = 0;
  70. memset(st,0,sizeof(st));
  71. int u,v,w;
  72. for(int i = 1 ; i < K ; ++i) {
  73. read(u);read(v);read(w);
  74. add(u,v);
  75. }
  76. idx = 0;tot = 0;
  77. dfs(1,0);
  78. for(int i = 2 ; i <= tot ; ++i) len[i] = len[i / 2] + 1;
  79. for(int j = 1 ; j <= 16 ; ++j) {
  80. for(int i = 1 ; i <= tot ; ++i) {
  81. st[i][j] = min_dep(st[i][j - 1],st[i + (1 << j - 1)][j - 1]);
  82. }
  83. }
  84. }
  85. }
  86. namespace Graph {
  87. struct node {
  88. int next,to;
  89. int64 val;
  90. }E[4000005];
  91. int head[1000005],sumE,pos[1000005],Ncnt,S;
  92. vector<int> vec[MAXN][2];
  93. int Line[200005],tot,sta[MAXK],top,faAux[MAXK],siz[MAXK],d[MAXK],pz[2][MAXK],tr[2][MAXK * 8];
  94. int64 dis[1000005];
  95. bool vis[1000005];
  96. bool cmp(int a,int b) {
  97. return Tree::dfn[a] < Tree::dfn[b];
  98. }
  99. void add(int u,int v,int64 c) {
  100. E[++sumE].to = v;
  101. E[sumE].next = head[u];
  102. E[sumE].val = c;
  103. head[u] = sumE;
  104. }
  105. void Init() {
  106. sumE = 0;Ncnt = 0;memset(head,0,sizeof(head));
  107. for(int i = 1 ; i <= N ; ++i) {vec[i][0].clear();vec[i][1].clear();}
  108. int a,b,d;
  109. int64 c;
  110. for(int i = 1 ; i <= M ; ++i) {
  111. read(a);read(b);read(c);read(d);
  112. pos[Ncnt + 1] = d;pos[Ncnt + 2] = d;
  113. vec[a][1].pb(Ncnt + 1);vec[b][0].pb(Ncnt + 2);
  114. add(Ncnt + 1,Ncnt + 2,c);
  115. Ncnt += 2;
  116. }
  117. S = ++Ncnt;
  118. pos[S] = 1;vec[1][0].pb(S);
  119. }
  120. void Build_SegmentTree(int id,int u,int L,int R) {
  121. tr[id][u] = ++Ncnt;
  122. if(L == R) {pz[id][Line[R]] = Ncnt;return;}
  123. int mid = (L + R) >> 1;
  124. Build_SegmentTree(id,u << 1,L,mid);
  125. Build_SegmentTree(id,u << 1 | 1,mid + 1,R);
  126. if(!id) {add(tr[id][u << 1],tr[id][u],0);add(tr[id][u << 1 | 1],tr[id][u],0);}
  127. else {add(tr[id][u],tr[id][u << 1],0);add(tr[id][u],tr[id][u << 1 | 1],0);}
  128. }
  129. void Add_Edge(int id,int u,int L,int R,int l,int r,int v,int64 c) {
  130. if(L == l && R == r) {
  131. if(!id) {add(tr[id][u],v,c);}
  132. else {add(v,tr[id][u],c);}
  133. return;
  134. }
  135. int mid = (L + R) >> 1;
  136. if(r <= mid) Add_Edge(id,u << 1,L,mid,l,r,v,c);
  137. else if(l > mid) Add_Edge(id,u << 1 | 1,mid + 1,R,l,r,v,c);
  138. else {Add_Edge(id,u << 1,L,mid,l,mid,v,c);Add_Edge(id,u << 1 | 1,mid + 1,R,mid + 1,r,v,c);}
  139. }
  140. void Build_AuxTree() {
  141. top = 0;
  142. sta[++top] = Line[1];faAux[Line[1]] = 0;
  143. int c = tot;
  144. for(int i = 2 ; i <= c ; ++i) {
  145. int f = Tree::lca(sta[top],Line[i]);
  146. while(top >= 1 && Tree::dep[sta[top]] > Tree::dep[f]) {
  147. if(top == 1 || Tree::dep[sta[top - 1]] <= Tree::dep[f]) {
  148. faAux[sta[top]] = f;
  149. }
  150. --top;
  151. }
  152. if(f != sta[top]) {
  153. faAux[f] = sta[top];
  154. sta[++top] = f;
  155. Line[++tot] = f;
  156. }
  157. sta[++top] = Line[i];
  158. faAux[Line[i]] = f;
  159. }
  160. sort(Line + 1,Line + tot + 1,cmp);
  161. for(int i = 1 ; i <= tot ; ++i) siz[Line[i]] = 1;
  162. for(int i = tot ; i >= 1 ; --i) {
  163. siz[faAux[Line[i]]] += siz[Line[i]];
  164. d[Line[i]] = i;
  165. }
  166. Build_SegmentTree(0,1,1,tot);
  167. Build_SegmentTree(1,1,1,tot);
  168. for(int i = 1 ; i <= tot ; ++i) {
  169. int u = Line[i];
  170. ++Ncnt;
  171. Add_Edge(0,1,1,tot,i,i,Ncnt,Tree::dep[u] - 1);
  172. Add_Edge(1,1,1,tot,i,i + siz[u] - 1,Ncnt,0);
  173. int f = faAux[u];
  174. if(f) {
  175. ++Ncnt;
  176. Add_Edge(0,1,1,tot,i,i + siz[u] - 1,Ncnt,Tree::dep[f] - 1);
  177. if(d[f] <= i - 1)
  178. Add_Edge(1,1,1,tot,d[f],i - 1,Ncnt,0);
  179. if(d[f] + siz[f] - 1 >= i + siz[u])
  180. Add_Edge(1,1,1,tot,i + siz[u],d[f] + siz[f] - 1,Ncnt,0);
  181. }
  182. }
  183. }
  184. void Build_Graph() {
  185. for(int i = 1 ; i <= N ; ++i) {
  186. tot = 0;
  187. for(int k = 0 ; k <= 1 ; ++k) {
  188. for(int j = 0 ; j < vec[i][k].size() ; ++j) {
  189. Line[++tot] = pos[vec[i][k][j]];
  190. }
  191. }
  192. sort(Line + 1,Line + tot + 1);
  193. tot = unique(Line + 1,Line + tot + 1) - Line - 1;
  194. sort(Line + 1,Line + tot + 1,cmp);
  195. Build_AuxTree();
  196. for(int k = 0 ; k <= 1 ; ++k) {
  197. for(int j = 0 ; j < vec[i][k].size() ; ++j) {
  198. int t = vec[i][k][j];
  199. if(!k) add(t,pz[k][pos[t]],0);
  200. else add(pz[k][pos[t]],t,0);
  201. }
  202. }
  203. }
  204. }
  205. void Dijkstra() {
  206. for(int i = 1 ; i <= Ncnt ; ++i) {
  207. dis[i] = 1e16;vis[i] = 0;
  208. }
  209. dis[S] = 0;
  210. Q.push(mp(-dis[S],S));
  211. while(!Q.empty()) {
  212. pair<int64,int> now = Q.top();Q.pop();
  213. int u = now.se;
  214. if(vis[u]) continue;
  215. vis[u] = 1;
  216. for(int i = head[u] ; i; i = E[i].next) {
  217. int v = E[i].to;
  218. if(dis[v] > dis[u] + E[i].val) {
  219. dis[v] = dis[u] + E[i].val;
  220. Q.push(mp(-dis[v],v));
  221. }
  222. }
  223. }
  224. }
  225. void Print() {
  226. for(int i = 2 ; i <= N ; ++i) {
  227. int64 ans = 1e16;
  228. for(int j = 0 ; j < vec[i][0].size() ; ++j) ans = min(ans,dis[vec[i][0][j]]);
  229. out(ans);enter;
  230. }
  231. }
  232. }
  233. void Solve() {
  234. read(N);read(M);read(K);
  235. Graph::Init();
  236. Tree::Init();
  237. Graph::Build_Graph();
  238. Graph::Dijkstra();
  239. Graph::Print();
  240. }
  241. int main() {
  242. #ifdef ivorysi
  243. freopen("f1.in","r",stdin);
  244. #endif
  245. int T;
  246. read(T);
  247. while(T--) Solve();
  248. return 0;
  249. }

md我zz吧

我代码是别人的两倍,运行时间也是别人的两倍啊

我附加点为什么最后都建到1000000去了,不应该啊,然后还0.5s?是LOJ的评测机扩充了我的想象力吗

好写???

没觉得好写啊???

我觉得刷新了我难写的上限啊???

思路和细节写的比NOI2018D2T2还累啊,我代码能力难道真的退化了???

【LOJ】#2270. 「SDOI2017」天才黑客的更多相关文章

  1. loj#2269. 「SDOI2017」切树游戏

    还是loj的机子快啊... 普通的DP不难想到,设F[i][zt]为带上根玩出zt的方案数,G[i][zt]为子树中的方案数,后面是可以用FWT优化的 主要是复习了下动态DP #include< ...

  2. loj#2002. 「SDOI2017」序列计数(dp 矩阵乘法)

    题意 题目链接 Sol 质数的限制并没有什么卵用,直接容斥一下:答案 = 忽略质数总的方案 - 没有质数的方案 那么直接dp,设\(f[i][j]\)表示到第i个位置,当前和为j的方案数 \(f[i ...

  3. @loj - 2004@ 「SDOI2017」硬币游戏

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 周末同学们非常无聊,有人提议,咱们扔硬币玩吧,谁扔的硬币正面次数 ...

  4. LOJ #2005. 「SDOI2017」相关分析 线段树维护回归直线方程

    题目描述 \(Frank\) 对天文学非常感兴趣,他经常用望远镜看星星,同时记录下它们的信息,比如亮度.颜色等等,进而估算出星星的距离,半径等等. \(Frank\) 不仅喜欢观测,还喜欢分析观测到的 ...

  5. [LOJ#2270][BZOJ4912][SDOI2017]天才黑客

    [LOJ#2270][BZOJ4912][SDOI2017]天才黑客 试题描述 SD0062 号选手小 Q 同学为了偷到 SDOI7012 的试题,利用高超的黑客技术潜入了 SDOI 出题组的内联网的 ...

  6. LibreOJ 2003. 「SDOI2017」新生舞会 基础01分数规划 最大权匹配

    #2003. 「SDOI2017」新生舞会 内存限制:256 MiB时间限制:1500 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据   题目描述 ...

  7. Loj #2192. 「SHOI2014」概率充电器

    Loj #2192. 「SHOI2014」概率充电器 题目描述 著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品--概率充电器: 「采用全新纳米级加工技术,实现元件与导线能否通电完 ...

  8. Loj #3096. 「SNOI2019」数论

    Loj #3096. 「SNOI2019」数论 题目描述 给出正整数 \(P, Q, T\),大小为 \(n\) 的整数集 \(A\) 和大小为 \(m\) 的整数集 \(B\),请你求出: \[ \ ...

  9. Loj #3093. 「BJOI2019」光线

    Loj #3093. 「BJOI2019」光线 题目描述 当一束光打到一层玻璃上时,有一定比例的光会穿过这层玻璃,一定比例的光会被反射回去,剩下的光被玻璃吸收. 设对于任意 \(x\),有 \(x\t ...

随机推荐

  1. ctags相关

    ctags相关 首先肯定是下载安装了.这点不用多讲,根据自己的操作系统或者平台,使用相应的包管理工具或者源码编译安装都可以. 下载完之后,在想要使用ctags帮助查找的文件夹(一般是项目的根目录)下输 ...

  2. 【BZOJ1304】[CQOI2009]叶子的染色(动态规划)

    [BZOJ1304][CQOI2009]叶子的染色(动态规划) 题面 BZOJ 洛谷 题解 很简单. 设\(f[i][0/1/2]\)表示以\(i\)为根的子树中,还有颜色为\(0/1/2\)(\(2 ...

  3. luogu1373 小a和uim之大逃离 (dp)

    直接设f[i][j][k][l][2]是在(i,j)时两人分数是k,l,复杂度会爆掉 但其实只需要知道两人分数只差就行了 所以设f[i][j][k][2],k是分数之差%(K+1),最后一位表示该谁走 ...

  4. c/c++ 判断两个实型的关系

    etc. minv=1e-10 or less x>y : x>y-minv x<y : x<y+minv x=y : fabs(x-y)<minv

  5. codeblocks调试

    1.Next instruction 逐指令 (有可能一行内有多条指令) (Alt+F7) Next line 逐行(有可能一条指令分成多行) (F7) Next instruction: -> ...

  6. Helm二:安装

    目录 Helm安装 Helm client安装 Helm tiller安装 Chart仓库配置 私有chart仓库 chart仓库的组成 创建本地仓库 chart仓库基本管理 Helm安装 Helm ...

  7. Spark记录-Scala语法基础

    参考:http://docs.scala-lang.org/cheatsheets/index.html.http://docs.scala-lang.org/.http://www.scala-la ...

  8. internal in C#

    说白了 被 internal 修饰的东西只能在本程序集(当前项目)内被使用. 被 protected internal 修饰的属性/方法 可以在其他项目中,被派生类使用 例如有两个项目app1和app ...

  9. 从零开始写一个武侠冒险游戏-0-开发框架Codea简介

    从零开始写一个武侠冒险游戏-0-开发框架Codea简介 作者:FreeBlues 修订记录 2016.06.21 初稿完成. 2016.08.03 增加对 XCode 项目文件的说明. 概述 本游戏全 ...

  10. 浏览器存储:cookie

    Cookie是什么:cookie是指存储在用户本地终端上的数据,同时它是与具体的web页面或者站点相关的.Cookie数据会自动在web浏览器和web服务器之间传输,也就是说HTTP请求发送时,会把保 ...