【题解】P5022 旅行

当给定你一颗树的时候,这题就是一道送分题,凉心啊!

但是给定你一颗基环树呢?

暴力断环直接跑。

但是数据范围\(n\le 1000\)

乱做就完事了。

考场上这样想的,对于\(m=n​\)的情况,得出来的最佳方案一定没有经过一条树边。那么我们直接枚举那条边不能走,直接\(O(n^2)​\)过就好了。

不过这样的算法有一个\(bug\),是因为\(dfs\)在节点上需要枚举哪个点最小,很可能被卡到\(O(n^3)\),但是\(ccf\)今年换配置了,而且不可能每个点都要枚举\(O(n)\),因为是一棵树,只有一种到达方式。那么就取得了\(96\)分的好成绩。

要是\(D1T2\)没有挂题我就1=了!!

悲伤QAQ

当然,针对上述那种被卡,有很简单的办法解决,我们用的是链式前向星,直接加边的时候把小的后面加进去就好了。

考场代码(\(96\))

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. inline int qr(){
  4. char c=getchar();
  5. int x=0,q=1;
  6. while(c<48||c>57)
  7. q=c==45?-1:q,c=getchar();
  8. while(c>=48&&c<=57)
  9. x=x*10+c-48,c=getchar();
  10. return q==-1?-x:x;
  11. }
  12. #define RP(t,a,b) for(int t=(a),edd=(b);t<=edd;t++)
  13. #define DRP(t,a,b) for(int t=(a),edd=(b);t>=edd;t--)
  14. #define ERP(t,a) for(int t=head[a];t;t=e[t].nx)
  15. #define more(a,b) (a)=(a)>(b)?(a):(b)
  16. #define few(a,b) (a)=(a)<(b)?(a):(b)
  17. typedef long long ll;
  18. const int maxn=5005;
  19. struct E{
  20. int to,num,nx;
  21. }e[maxn<<1];
  22. int head[maxn];
  23. bool can[maxn];
  24. int cnt;
  25. inline void add(int fr,int to,int num,bool f){
  26. e[++cnt]=(E){to,num,head[fr]};
  27. head[fr]=cnt;
  28. if(f)
  29. add(to,fr,num,0);
  30. }
  31. int n,m;
  32. int ans[maxn];
  33. int dfn[maxn];
  34. bool usd[maxn];
  35. int top;
  36. bool better;
  37. const int inf=0x3f3f3f3f;
  38. void dfs(int now,int last,int pos){
  39. //cout<<now<<' '<<last<<' '<<pos<<endl;
  40. dfn[++top]=now;
  41. int sav=inf,pin=0;
  42. bool flg=1;
  43. while(flg){
  44. flg=0;
  45. sav=inf;
  46. pin=0;
  47. ERP(t,now)
  48. if((e[t].to!=last)&&(!usd[e[t].to])&&(e[t].to<sav)&&(!can[e[t].num]))
  49. sav=e[t].to,pin=t,flg=1;
  50. //cout<<"now="<<now<<" sav="<<sav<<" flg="<<flg<<endl;
  51. if(flg)
  52. usd[e[pin].to]=1,dfs(e[pin].to,now,pos+1);
  53. }
  54. }
  55. int t1,t2,t3;
  56. inline void init(){
  57. n=qr();
  58. m=qr();
  59. memset(ans,0x3f,sizeof ans);
  60. RP(t,1,m){
  61. t1=qr();
  62. t2=qr();
  63. add(t1,t2,t,1);
  64. }
  65. if(m==n-1){
  66. dfs(1,0,1);
  67. RP(t,1,n)
  68. cout<<dfn[t]<<' ';
  69. cout<<endl;
  70. return;
  71. }
  72. else{
  73. RP(t,1,m){
  74. top=0;
  75. better=0;
  76. memset(usd,0,sizeof usd);
  77. can[t]=1;
  78. dfs(1,0,1);
  79. can[t]=0;
  80. if(top==n){
  81. RP(t,1,n){
  82. if(dfn[t]!=ans[t]){
  83. if(dfn[t]<ans[t])
  84. better=1;
  85. break;
  86. }
  87. }
  88. }
  89. if(better&&top==n)
  90. RP(t,1,n)
  91. ans[t]=dfn[t];
  92. }
  93. }
  94. RP(t,1,n)
  95. cout<<ans[t]<<' ';
  96. cout<<endl;
  97. return;
  98. }
  99. int main(){
  100. // freopen("travel.in","r",stdin);
  101. // freopen("travel.out","w",stdout);
  102. init();
  103. return 0;
  104. }

\(AC\)代码

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. inline int qr() {
  4. char c=getchar();
  5. int x=0,q=1;
  6. while(c<48||c>57)
  7. q=c==45?-1:q,c=getchar();
  8. while(c>=48&&c<=57)
  9. x=x*10+c-48,c=getchar();
  10. return q==-1?-x:x;
  11. }
  12. #define RP(t,a,b) for(int t=(a),edd=(b);t<=edd;t++)
  13. #define DRP(t,a,b) for(int t=(a),edd=(b);t>=edd;t--)
  14. #define ERP(t,a) for(int t=head[a];t;t=e[t].nx)
  15. #define more(a,b) (a)=(a)>(b)?(a):(b)
  16. #define few(a,b) (a)=(a)<(b)?(a):(b)
  17. typedef long long ll;
  18. const int maxn=5005;
  19. struct E {
  20. int to,num,nx;
  21. } e[maxn<<1];
  22. struct sav {
  23. int fr,to,num;
  24. } data[maxn<<1];
  25. int head[maxn];
  26. bool can[maxn];
  27. int cnt;
  28. inline bool cmp(sav a,sav b) {
  29. return a.to>b.to;
  30. }
  31. inline void add(int fr,int to,int num) {
  32. e[++cnt]=(E) {
  33. to,num,head[fr]
  34. };
  35. head[fr]=cnt;
  36. }
  37. int n,m;
  38. int ans[maxn];
  39. int dfn[maxn];
  40. bool usd[maxn];
  41. int top;
  42. bool better;
  43. const int inf=0x3f3f3f3f;
  44. void dfs(int now,int last,int pos) {
  45. dfn[++top]=now;
  46. ERP(t,now) {
  47. if((e[t].to!=last)&&(!usd[e[t].to])&&(!can[e[t].num]))
  48. usd[e[t].to]=1,dfs(e[t].to,now,pos+1);
  49. }
  50. }
  51. int t1,t2,t3;
  52. inline void init() {
  53. n=qr();
  54. m=qr();
  55. memset(ans,0x3f,sizeof ans);
  56. RP(t,1,m) {
  57. t1=qr();
  58. t2=qr();
  59. data[t].to=t1;
  60. data[t].fr=t2;
  61. data[t+m].fr=t1;
  62. data[t+m].to=t2;
  63. data[t].num=t;
  64. data[t+m].num=t;
  65. }
  66. sort(data+1,data+m+m+1,cmp);
  67. RP(t,1,m+m)
  68. add(data[t].fr,data[t].to,data[t].num);
  69. if(m==n-1) {
  70. dfs(1,0,1);
  71. RP(t,1,n)
  72. cout<<dfn[t]<<' ';
  73. cout<<endl;
  74. return;
  75. } else {
  76. RP(t,1,m) {
  77. top=0;
  78. better=0;
  79. memset(usd,0,sizeof usd);
  80. can[t]=1;
  81. dfs(1,0,1);
  82. can[t]=0;
  83. if(top==n) {
  84. RP(t,1,n) {
  85. if(dfn[t]!=ans[t]) {
  86. if(dfn[t]<ans[t])
  87. better=1;
  88. break;
  89. }
  90. }
  91. }
  92. if(better&&top==n)
  93. RP(t,1,n)
  94. ans[t]=dfn[t];
  95. }
  96. }
  97. RP(t,1,n)
  98. cout<<ans[t]<<' ';
  99. cout<<endl;
  100. return;
  101. }
  102. int main() {
  103. // freopen("travel.in","r",stdin);
  104. // freopen("travel.out","w",stdout);
  105. init();
  106. return 0;
  107. }

【题解】 P5022旅行的更多相关文章

  1. 【luogu P5022 旅行】 题解

    题目连接:https://www.luogu.org/problemnew/show/P5022 \(NOIP2018 DAY2T1\) 考场上只写了60分,很容易想到当 m = n - 1 时的树的 ...

  2. 洛谷 P5022 旅行——题解

    发现大部分题解都是O(n^2)的复杂度,这里分享一个O(n)复杂度的方法. 题目传送 首先前60%的情况,图是一棵无根树,只要从1开始DFS,每次贪心走点的编号最小的点就行了.(为什么?因为当走到一个 ...

  3. 洛谷P5022 旅行 题解 去环/搜索

    题目链接:https://www.luogu.org/problem/P5022 这道题目一开始看的时候没有思路,但是看到数据范围里面有一个: \(m = n-1\) 或 \(m = n\) ,一下子 ...

  4. luogu题解 P5022 【旅行】

    本人的代码可以说洛谷最简单的了 我的存图方式有些与众不同 a[5000][5000]中第一个下标表示第几个点,第二个表示与点相连的点 虽然比前向星废内存但时间极快,大概是O(n)的. 现在步入正题 6 ...

  5. 洛谷P5022 旅行 题解

    前面几个代码都是部分分代码,最后一个才是AC了的,所以最后一个有详细注释 安利一发自己的Blog 这是提高组真题,233有点欧拉回路的感觉. 题目大意: 一个 连通 图,双向边 ,无重边 , 访问图中 ...

  6. 竞赛题解 - NOIP2018 旅行

    \(\mathcal {NOIP2018} 旅行 - 竞赛题解\) 坑还得一层一层的填 填到Day2T1了 洛谷 P5022 题目 (以下copy自洛谷,有删减/修改 (●ˇ∀ˇ●)) 题目描述 小 ...

  7. P5022 旅行

    原题链接  https://www.luogu.org/problem/P5022 本着快csp了,做点往年的NOIp的题试试水来着,没想到水这么深 难度还挺大的,耗了我一天的时间(可能是我太菜了) ...

  8. P5022 旅行 (NOIP2018)

    传送门 先考虑是一颗树的情况 求最小的 dfs 序 显然按儿子编号从小到大dfs 如果有多一条边怎么办 显然会有一条边不用走 直接枚举删那条边然后每次都暴力 dfs 复杂度 $O(n^2)$ 注意每个 ...

  9. 【题解】旅行-C++

    Description 某趟列车的最大载客容量为V人,沿途共有n个停靠站,其中始发站为第1站,终点站为第n站.在第1站至第n-1站之 间,共有m个团队申请购票搭乘,若规定:(1)对于某个团队的购票申请 ...

随机推荐

  1. SecureCRT设置每次连接使用后的日志

  2. Difference between a Hard Link and Soft (Symbolic) Link

    Within the Unix/Linux file system, linking lets you create file shortcuts to link one or more files. ...

  3. JS版汉字与拼音互转终极方案,附简单的JS拼音

    前言 网上关于JS实现汉字和拼音互转的文章很多,但是比较杂乱,都是互相抄来抄去,而且有的不支持多音字,有的不支持声调,有的字典文件太大,还比如有时候我仅仅是需要获取汉字拼音首字母却要引入200kb的字 ...

  4. C# 格式化 中文星期 显示

    最近有些小忙,直接贴代码吧, /// <summary> /// 获取系统的星期 /// </summary> /// <param name="dt" ...

  5. 【java】Java中十六进制转换 Integer.toHexString()到底做了什么?什么时候会用到它?为什么要用它?byte为什么要&0xff?为什么要和0xff做与运算?

    参考地址:http://www.cnblogs.com/think-in-java/p/5527389.html 参考地址:https://blog.csdn.net/scyatcs/article/ ...

  6. Intellij IDEA 拷贝的项目变为红色名字

    Intellij IDEA 拷贝的项目变为红色名字 学习了:https://blog.csdn.net/lishaoran369/article/details/72991805 settings & ...

  7. 【Excle数据透视表】如何复制数据透视表

    左边创建完数据透视表,右边是复制过去的部分数据透视表---显示数值状态的内容,为什么复制过来的不是数据透视表呢? 解决办法: 全选定数据透视表再进行粘贴复制 步骤一 单击数据透视表任意单元格→分析→操 ...

  8. jquery方法

    $.inArray(被判断的量,ArrayName);  如果存在返回索引值,如果不存在返回-1 $.unique() 数组去重   根据去重前后的长度,判断是否有重复 $.each(被遍历的数组,f ...

  9. webdriver.py--解说

    一.全局操作类 start_session 使用指定的desired capabilities创建一个会话(session)start_client 新建一个webdriver会话session前调用 ...

  10. Lua学习七----------Lua函数

    © 版权声明:本文为博主原创文章,转载请注明出处 1.Lua函数 - 完成指定的任务,这种情况下函数作为调用语句使用 - 计算并返回值,这种情况下函数作为赋值语句的表达式使用 - Lua函数可以返回多 ...