#2691. 「POI2012」约会 Rendezvous

这题我简直不想说什么了,什么素质,卡常数……

“每个顶点有且仅有一条出边”,所以是一道基环树的题,首先tarjan缩点,在缩完点后的图上求a,b的LCA,如果LCA在环内,求出a,b分别对应环中的哪一个点,显然这两个点中的一个为最优解。

我一开始是在求LCA时顺便求出的a,b对应的点,这样使常数变大,虽然在LOJ和bzoj上都A了,但是在某OJ上疯狂T94,调了一下午+一晚上……

这个可以提前一边dfs预处理出来:

  1. void dfs2(int x,int ci,int ff)
  2. {
  3. incir[x]=ci;
  4. for(int i=f(x);i;i=n(i))
  5. if(v(i)!=ff && belong[v(i)]!=belong[x])
  6. dfs2(v(i),ci,x);
  7. }
  8.  
  9. for(int i=;i<=tot;i++)
  10. if(scc[i].size()>)
  11. for(int j=;j<scc[i].size();j++)
  12. dfs2(scc[i][j],scc[i][j],d[scc[i][j]]);

感谢ooo帮忙卡常以及mikufun大佬提醒。

  1. #include<iostream>
  2. #include<cstring>
  3. #include<cstdio>
  4. #include<vector>
  5. #include<queue>
  6. #include<cmath>
  7. #define rint register int
  8. #define MAXN 500010
  9. #define ma(x) memset(x,0,sizeof(x))
  10. #define max(a,b) ((a)>(b)?(a):(b))
  11. #define min(a,b) ((a)<(b)?(a):(b))
  12. const int L=<<|;
  13. char buffer[L],*S,*T;
  14. #define getchar() ((S==T&&(T=(S=buffer)+fread(buffer,1,L,stdin),S==T))?EOF:*S++)
  15. using namespace std;
  16. struct edge
  17. {
  18. int u,v,nxt;
  19. #define u(x) ed[x].u
  20. #define v(x) ed[x].v
  21. #define n(x) ed[x].nxt
  22. #define v2(x) ed2[x].v
  23. #define n2(x) ed2[x].nxt
  24. }ed[MAXN],ed2[MAXN];
  25. int first[MAXN],num_e;
  26. #define f(x) first[x]
  27. int first2[MAXN],num_e2;
  28. #define f2(x) first2[x]
  29.  
  30. int n,k;
  31. int d[MAXN];
  32. inline void add(rint u,rint v);
  33. inline void add2(rint u,rint v);
  34. inline void swap(rint *a,rint* b)
  35. {
  36. *a = *a ^ *b;
  37. *b = *a ^ *b;
  38. *a = *a ^ *b;
  39. }
  40. inline int read()
  41. {
  42. int s=;char a=getchar();
  43. while(a<''||a>'')a=getchar();
  44. while(a>=''&&a<=''){s=s*+a-'';a=getchar();}
  45. return s;
  46. }
  47. int dfn[MAXN],low[MAXN],cnt;
  48. int stack[MAXN],top;
  49. bool vi[MAXN];
  50. int tot,belong[MAXN];
  51. vector<int> scc[MAXN];
  52. int sor[MAXN],ooo;
  53. int intree[MAXN],tr;
  54. void tarjan(int x)
  55. {
  56. dfn[x]=++cnt;low[x]=cnt;
  57. vi[x]=;
  58. stack[++top]=x;
  59. for(rint i=f(x);i;i=n(i))
  60. if(!dfn[v(i)])tarjan(v(i)),low[x]=min(low[x],low[v(i)]);
  61. else if(vi[v(i)])low[x]=min(low[x],low[v(i)]);
  62. if(dfn[x]==low[x])
  63. {
  64. tot++;vi[x]=;ooo=;
  65. while(stack[top]!=x)
  66. {
  67. belong[stack[top]]=tot;
  68. scc[tot].push_back(stack[top]);
  69. sor[stack[top]]=++ooo;
  70. vi[stack[top--]]=;
  71. }
  72. sor[stack[top]]=++ooo;
  73. scc[tot].push_back(stack[top]);
  74. belong[stack[top--]]=tot;
  75. }
  76. }
  77.  
  78. int dep[MAXN],fa[MAXN][];
  79. int bin[];
  80. void dfs(int x,int ff,int de,int tr)
  81. {
  82. fa[x][]=ff;dep[x]=de;intree[x]=tr;
  83. for(rint i=f2(x);i;i=n2(i))
  84. if(v2(i)!=ff && !dep[v2(i)])
  85. dfs(v2(i),x,de+,tr);
  86. }
  87. int LCA(int a,int b,int x,int y,int &xi,int &yi,int &xx,int &yy)
  88. {
  89. xi=yi=;xx=a;yy=b;
  90. bool pd=;
  91. if(dep[x]>dep[y]){swap(x,y);swap(xx,yy);pd=;}
  92. if(dep[x]!=dep[y])
  93. {
  94. while(dep[x]!=dep[y]-)
  95. for(rint i=;;i++)
  96. if(dep[fa[y][i]]-<dep[x])
  97. {y=fa[y][i-];yi+=bin[i-];break;}
  98. yy=scc[y][];yy=d[yy];
  99. y=fa[y][],yi++;
  100. }
  101. if(x==y)
  102. {
  103. if(pd){swap(xi,yi);swap(xx,yy);}
  104. return y;
  105. }
  106. while(fa[x][]!=fa[y][])
  107. for(rint i=;;i++)
  108. if(fa[x][i]==fa[y][i])
  109. {x=fa[x][i-],y=fa[y][i-];xi+=bin[i-],yi+=bin[i-];break;}
  110. if(pd){swap(xi,yi);swap(x,y);}++xi,++yi;
  111. xx=d[scc[x][]],yy=d[scc[y][]];
  112. return fa[x][];
  113. }
  114. int du[MAXN];
  115. signed main()
  116. {
  117. // freopen("1.in","r",stdin);
  118. // freopen("in.txt","r",stdin);
  119.  
  120. bin[]=;for(rint i=;i<;i++)bin[i]=bin[i-]<<;
  121. n=read(),k=read();
  122. for(rint i=;i<=n;i++){d[i]=read();add(d[i],i);}
  123. for(rint i=;i<=n;i++)
  124. if(!dfn[i])tarjan(i);
  125. for(rint i=;i<=num_e;i++)
  126. if(belong[u(i)]!=belong[v(i)])
  127. add2(belong[u(i)],belong[v(i)]),du[belong[v(i)]]++;
  128. for(rint i=;i<=tot;i++)
  129. if(!du[i])dfs(i,,,++tr);
  130. for(rint i=;i<;i++)
  131. for(rint j=;j<=tot;j++)
  132. fa[j][i]=fa[fa[j][i-]][i-];
  133. int a,b,xi,yi,xx,yy;
  134. int lca,t1,t2,x1,x2,y1,y2;
  135. for(rint i=;i<=k;i++)
  136. {
  137. a=read(),b=read();
  138. if(intree[belong[a]]!=intree[belong[b]]){puts("-1 -1");continue;}
  139. lca=LCA(a,b,belong[a],belong[b],xi,yi,xx,yy);
  140. if(!lca){puts("-1 -1");continue;}
  141. if(scc[lca].size()==){printf("%d %d\n",xi,yi);continue;}
  142. t1=(sor[xx]-sor[yy]+scc[belong[xx]].size()),
  143. t2=(sor[yy]-sor[xx]+scc[belong[xx]].size());
  144. if(t1>=scc[belong[xx]].size())t1-=scc[belong[xx]].size();
  145. if(t2>=scc[belong[xx]].size())t2-=scc[belong[xx]].size();
  146. swap(t1,t2);
  147. x1=xi,y1=yi+t2;
  148. x2=xi+t1,y2=yi;
  149. int ma1=max(x1,y1),ma2=max(x2,y2),mi1=min(x1,y1),mi2=min(x2,y2);
  150. if(ma1!=ma2){ma1<ma2?printf("%d %d\n",x1,y1):printf("%d %d\n",x2,y2);}
  151. else if(mi1!=mi2){mi1<mi2?printf("%d %d\n",x1,y1):printf("%d %d\n",x2,y2);}
  152. else{x1>=y1?printf("%d %d\n",x1,y1):printf("%d %d\n",x2,y2);}
  153. }
  154. }
  155. inline void add(rint u,rint v)
  156. {
  157. u(++num_e)=u;
  158. v(num_e)=v;
  159. n(num_e)=f(u);
  160. f(u)=num_e;
  161. }
  162. inline void add2(rint u,rint v)
  163. {
  164. v2(++num_e2)=v;
  165. n2(num_e2)=f2(u);
  166. f2(u)=num_e2;
  167. }

疯狂T94的沙雕代码

  1. #include<iostream>
  2. #include<cstring>
  3. #include<cstdio>
  4. #include<vector>
  5. #include<queue>
  6. #include<cmath>
  7. #define rint register int
  8. #define MAXN 500010
  9. #define ma(x) memset(x,0,sizeof(x))
  10. #define max(a,b) ((a)>(b)?(a):(b))
  11. #define min(a,b) ((a)<(b)?(a):(b))
  12. const int L=<<|;
  13. char buffer[L],*S,*T;
  14. #define getchar() ((S==T&&(T=(S=buffer)+fread(buffer,1,L,stdin),S==T))?EOF:*S++)
  15. using namespace std;
  16. struct edge
  17. {
  18. int u,v,nxt;
  19. #define u(x) ed[x].u
  20. #define v(x) ed[x].v
  21. #define n(x) ed[x].nxt
  22. #define v2(x) ed2[x].v
  23. #define n2(x) ed2[x].nxt
  24. }ed[MAXN],ed2[MAXN];
  25. int first[MAXN],num_e;
  26. #define f(x) first[x]
  27. int first2[MAXN],num_e2;
  28. #define f2(x) first2[x]
  29.  
  30. int n,k;
  31. int d[MAXN];
  32. inline void add(rint u,rint v);
  33. inline void add2(rint u,rint v);
  34. inline void swap(rint *a,rint* b)
  35. {
  36. *a = *a ^ *b;
  37. *b = *a ^ *b;
  38. *a = *a ^ *b;
  39. }
  40. inline int read()
  41. {
  42. int s=;char a=getchar();
  43. while(a<''||a>'')a=getchar();
  44. while(a>=''&&a<=''){s=s*+a-'';a=getchar();}
  45. return s;
  46. }
  47. int dfn[MAXN],low[MAXN],cnt;
  48. int stack[MAXN],top;
  49. bool vi[MAXN];
  50. int tot,belong[MAXN];
  51. vector<int> scc[MAXN];
  52. int sor[MAXN],ooo;
  53. int intree[MAXN],tr;
  54. int incir[MAXN],ci;
  55. void tarjan(int x)
  56. {
  57. dfn[x]=++cnt;low[x]=cnt;
  58. vi[x]=;
  59. stack[++top]=x;
  60. for(rint i=f(x);i;i=n(i))
  61. if(!dfn[v(i)])tarjan(v(i)),low[x]=min(low[x],low[v(i)]);
  62. else if(vi[v(i)])low[x]=min(low[x],low[v(i)]);
  63. if(dfn[x]==low[x])
  64. {
  65. tot++;vi[x]=;ooo=;
  66. while(stack[top]!=x)
  67. {
  68. belong[stack[top]]=tot;
  69. scc[tot].push_back(stack[top]);
  70. sor[stack[top]]=++ooo;
  71. vi[stack[top--]]=;
  72. }
  73. sor[stack[top]]=++ooo;
  74. scc[tot].push_back(stack[top]);
  75. belong[stack[top--]]=tot;
  76. }
  77. }
  78.  
  79. int dep[MAXN],fa[MAXN][];
  80. int bin[];
  81. void dfs(int x,int ff,int de,int tr)
  82. {
  83. fa[x][]=ff;dep[x]=de;intree[x]=tr;
  84. for(rint i=f2(x);i;i=n2(i))
  85. if(v2(i)!=ff && !dep[v2(i)])
  86. dfs(v2(i),x,de+,tr);
  87. }
  88. void dfs2(int x,int ci,int ff)
  89. {
  90. incir[x]=ci;
  91. for(int i=f(x);i;i=n(i))
  92. if(v(i)!=ff && belong[v(i)]!=belong[x])
  93. dfs2(v(i),ci,x);
  94. }
  95. int LCA(int x,int y)
  96. {
  97. if(dep[x]>dep[y])swap(x,y);
  98. while(dep[x]!=dep[y])
  99. for(rint i=;;i++)
  100. if(dep[fa[y][i]]<dep[x])
  101. {y=fa[y][i-];break;}
  102. if(x==y){return y;}
  103. while(fa[x][]!=fa[y][])
  104. for(rint i=;;i++)
  105. if(fa[x][i]==fa[y][i])
  106. {x=fa[x][i-],y=fa[y][i-];break;}
  107. return fa[x][];
  108. }
  109. int du[MAXN];
  110. signed main()
  111. {
  112. // freopen("1.in","r",stdin);
  113. // freopen("in.txt","r",stdin);
  114.  
  115. bin[]=;for(rint i=;i<;i++)bin[i]=bin[i-]<<;
  116. n=read(),k=read();
  117. for(rint i=;i<=n;i++){d[i]=read();add(d[i],i);}
  118. for(rint i=;i<=n;i++)
  119. if(!dfn[i])tarjan(i);
  120. for(rint i=;i<=num_e;i++)
  121. if(belong[u(i)]!=belong[v(i)])
  122. add2(belong[u(i)],belong[v(i)]),du[belong[v(i)]]++;
  123. for(rint i=;i<=tot;i++)
  124. if(!du[i])dfs(i,,,++tr);
  125. for(rint i=;i<;i++)
  126. for(rint j=;j<=tot;j++)
  127. fa[j][i]=fa[fa[j][i-]][i-];
  128. for(int i=;i<=tot;i++)
  129. if(scc[i].size()>)
  130. for(int j=;j<scc[i].size();j++)
  131. dfs2(scc[i][j],scc[i][j],d[scc[i][j]]);
  132. int a,b,xi,yi,xx,yy;
  133. int lca,t1,t2,x1,x2,y1,y2;
  134. for(rint i=;i<=k;i++)
  135. {
  136. a=read(),b=read();
  137. if(intree[belong[a]]!=intree[belong[b]]){puts("-1 -1");continue;}
  138. if(incir[a]==incir[b])
  139. {
  140. lca=LCA(belong[a],belong[b]);
  141. printf("%d %d\n",dep[belong[a]]-dep[lca],dep[belong[b]]-dep[lca]);
  142. continue;
  143. }
  144. else
  145. xx=incir[a],yy=incir[b],xi=dep[belong[a]]-dep[belong[incir[a]]],yi=dep[belong[b]]-dep[belong[incir[b]]];
  146. t1=(sor[xx]-sor[yy]+scc[belong[xx]].size()),
  147. t2=(sor[yy]-sor[xx]+scc[belong[xx]].size());
  148. if(t1>=scc[belong[xx]].size())t1-=scc[belong[xx]].size();
  149. if(t2>=scc[belong[xx]].size())t2-=scc[belong[xx]].size();
  150. swap(t1,t2);
  151. x1=xi,y1=yi+t2;
  152. x2=xi+t1,y2=yi;
  153. int ma1=max(x1,y1),ma2=max(x2,y2),mi1=min(x1,y1),mi2=min(x2,y2);
  154. if(ma1!=ma2){ma1<ma2?printf("%d %d\n",x1,y1):printf("%d %d\n",x2,y2);}
  155. else if(mi1!=mi2){mi1<mi2?printf("%d %d\n",x1,y1):printf("%d %d\n",x2,y2);}
  156. else{x1>=y1?printf("%d %d\n",x1,y1):printf("%d %d\n",x2,y2);}
  157. }
  158. }
  159. inline void add(rint u,rint v)
  160. {
  161. u(++num_e)=u;
  162. v(num_e)=v;
  163. n(num_e)=f(u);
  164. f(u)=num_e;
  165. }
  166. inline void add2(rint u,rint v)
  167. {
  168. v2(++num_e2)=v;
  169. n2(num_e2)=f2(u);
  170. f2(u)=num_e2;
  171. }

改完后的AC代码

「POI2012」约会 Rendezvous的更多相关文章

  1. 「POI2012」井 Well

    description 你要挖井,\(n\)个地面的高度可视为\(h_i\),每次操作你可以将一个\(h_i-1\),你最多可执行\(m\)次操作. 你要任选其中一个\(h_i\)挖到\(0\),问你 ...

  2. POJ1061 青蛙的约会 和 LOJ2721 「NOI2018」屠龙勇士

    青蛙的约会 Language:Default 青蛙的约会 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 133470 Accep ...

  3. 「Luogu4556」Vani有约会-雨天的尾巴

    「Luogu4556」Vani有约会-雨天的尾巴 传送门 很显然可以考虑树上差分+桶,每次更新一条链就是把这条链上的点在桶对应位置打上 \(1\) 的标记, 最后对每个点取桶中非零值的位置作为答案即可 ...

  4. 「译」JUnit 5 系列:条件测试

    原文地址:http://blog.codefx.org/libraries/junit-5-conditions/ 原文日期:08, May, 2016 译文首发:Linesh 的博客:「译」JUni ...

  5. 「译」JUnit 5 系列:扩展模型(Extension Model)

    原文地址:http://blog.codefx.org/design/architecture/junit-5-extension-model/ 原文日期:11, Apr, 2016 译文首发:Lin ...

  6. JavaScript OOP 之「创建对象」

    工厂模式 工厂模式是软件工程领域一种广为人知的设计模式,这种模式抽象了创建具体对象的过程.工厂模式虽然解决了创建多个相似对象的问题,但却没有解决对象识别的问题. function createPers ...

  7. 「C++」理解智能指针

    维基百科上面对于「智能指针」是这样描述的: 智能指针(英语:Smart pointer)是一种抽象的数据类型.在程序设计中,它通常是经由类型模板(class template)来实做,借由模板(tem ...

  8. 「JavaScript」四种跨域方式详解

    超详细并且带 Demo 的 JavaScript 跨域指南来了! 本文基于你了解 JavaScript 的同源策略,并且了解使用跨域跨域的理由. 1. JSONP 首先要介绍的跨域方法必然是 JSON ...

  9. 「2014-5-31」Z-Stack - Modification of Zigbee Device Object for better network access management

    写一份赏心悦目的工程文档,是很困难的事情.若想写得完善,不仅得用对工具(use the right tools),注重文笔,还得投入大把时间,真心是一件难度颇高的事情.但,若是真写好了,也是善莫大焉: ...

随机推荐

  1. git diff 笔记

    有一个 lab1 一个lab2 lab2 是比lab1 新的版本 但是Lab1 中有一些写的新代码,想要保留到lab2 中 直接使用patch 会把 lab2 回退到lab1 或lab1 更新到lab ...

  2. ubuntu上安装nodejs和npm

    在使用npm时,特别注意nodejs的版本问题. 一般选择源码安装

  3. Vue--moment时间格式插件安装和使用

    使用链接:http://momentjs.cn/ 1.安装monent 2.导入 3.过滤器   4.template模板使用:

  4. 注解2 --- 自定义 Annotation --- 技术搬运工(尚硅谷)

    定义新的 Annotation 类型使用 @interface 关键字 自定义注解自动继承了java.lang.annotation.Annotation接口 Annotation 的成员变量在 An ...

  5. CSS预处理——LESS

    LESS是什么? less是一门CSS预处理语言.由于CSS本身并不是程序式语言,不方便维护和扩展,没有变量.函数.作用域等概念.而LESS在CSS的基础语法之上,引入了变量.Mixin混入.运算以及 ...

  6. Python3.7.4入门-5输入输出

    5 输入输出 5.1 格式化字符串字面值 在字符串的开始引号或三引号之前加上一个 f 或 F .在此字符串中,你可以在 { 和 } 字符之间写可以引用的变量或字面值的 Python 表达式. > ...

  7. Intellij:用Intellij出的Gradle插件进行开发

    前言:之前看到网上大部分的Intellij开发教程都是采用Intellij官方文档的那个版本,配置Intellij SDK一大堆的. 现在给大家介绍简单的方法吧,我们组内大神找到的.我们需要用到的是I ...

  8. bzoj1877 晨跑

    Description Elaxia最近迷恋上了空手道,他为自己设定了一套健身计划,比如俯卧撑.仰卧起坐等 等,不过到目前为止,他 坚持下来的只有晨跑. 现在给出一张学校附近的地图,这张地图中包含N个 ...

  9. flask 与celery

    在flask 中使用celery 是特别简单的,celery官网都没有特别介绍如何使用. 使用celery首先要知道怎么配置celery.   1. 实例化celery celery = Celery ...

  10. 数据分析1:安装tushare安装包

    1. 2. 3.重点内容