题目链接


Solution

  1. 非正解

    似乎比较蛇啊,先个一个部分分做法,最短路+\(DP\).

    在求最短路的堆或者队列中存储元素 \(dis_{i,j}\) 代表 \(i\) 这个节点,走了 \(j\) 条边的距离.

    然后跑堆优化 \(Dijkstra\) 或者 SPFA 即可.

    复杂度 \(O(N*nlog(n))\).

    其中 \(N\) 代表要走的边条数, \(n\) 代表节点数 . 但是这题 \(N\) 有 \(10^6\) ...

    洛谷上可以过掉 \(49\) 分.

    不过只要 \(N\) 小一点,这个算法明显更优啊...

  2. 正解

    虽然这题 \(N\) 很大,但是 \(n\) 超级小啊... 只有 \(10^2\) ...

    于是可以用 \(Floyd\) 跑最短路,然后呢??

    倍增。

    令 \(dis_{i,j,k}\) 代表从 \(i\) 到 \(j\) 走了 \(2^k\) 条边的最小距离.

    然后 \(Floyd\) 转移的时候利用和倍增跳 LCA 差不多的方式转移即可.

    (具体可以看代码)

    时间复杂度 \(O(n^3*log(N))\).

另外此题还需要一点离散化.


Code

49分:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int maxn=10008;
  4. struct sj{int to,next,w;}a[maxn];
  5. struct node{int u,k;};
  6. int head[maxn],size,cnt;
  7. int x[maxn],y[maxn],w[maxn];
  8. int to[maxn],num,n,t,S,E;
  9. map<int,int>dis[508],v[508];
  10. map<int,int>js[508];
  11. map<int,int>kkk;
  12. int read()
  13. {
  14. char ch=getchar(); int f=1,w=0;
  15. while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
  16. while(ch<='9'&&ch>='0'){w=w*10+ch-'0';ch=getchar();}
  17. return f*w;
  18. }
  19. void add(int x,int y,int w)
  20. {
  21. a[++size].to=y;
  22. a[size].next=head[x];
  23. head[x]=size;
  24. a[size].w=w;
  25. }
  26. void spfa()
  27. {
  28. queue<node>q;
  29. q.push((node){S,0});
  30. dis[S][0]=0; v[S][0]=1;
  31. js[S][0]++;
  32. while(!q.empty())
  33. {
  34. node x=q.front();q.pop();
  35. int u=x.u,k=x.k;
  36. if(k==n)continue;
  37. for(int i=head[u];i;i=a[i].next)
  38. {
  39. int tt=a[i].to;
  40. if(!js[tt][k+1])dis[tt][k+1]=192608173,js[tt][k+1]++;
  41. if(dis[tt][k+1]>dis[u][k]+a[i].w)
  42. {
  43. dis[tt][k+1]=dis[u][k]+a[i].w;
  44. if(!v[tt][k+1])
  45. {
  46. q.push((node){tt,k+1});
  47. v[tt][k+1]=1;
  48. }
  49. }
  50. }
  51. v[u][k]=0;
  52. }
  53. }
  54. void pre()
  55. {
  56. sort(to+1,to+num+1);
  57. int last=192608173;
  58. for(int i=1;i<=num;i++)
  59. {
  60. if(to[i]!=last)
  61. {
  62. kkk[to[i]]=++cnt;
  63. last=to[i];
  64. }
  65. }
  66. for(int i=1;i<=t;i++)
  67. {
  68. x[i]=kkk[x[i]],y[i]=kkk[y[i]];
  69. //cout<<x[i]<<' '<<y[i]<<endl;
  70. add(x[i],y[i],w[i]);
  71. add(y[i],x[i],w[i]);
  72. }
  73. }
  74. int main()
  75. {
  76. n=read(); t=read(); S=read(); E=read();
  77. for(int i=1;i<=t;i++)
  78. {
  79. w[i]=read();
  80. x[i]=read(); y[i]=read();
  81. to[++num]=x[i]; to[++num]=y[i];
  82. }
  83. pre(); S=kkk[S],E=kkk[E];
  84. spfa();
  85. cout<<dis[E][n]<<endl;
  86. }


100分:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int maxn=10008;
  4. struct node{int u,k;};
  5. int cnt;
  6. int x[maxn],y[maxn],w[maxn];
  7. int to[maxn],num,n,t,S,E;
  8. int dis[508][508][22],ans[508][508];
  9. map<int,int>kkk;
  10. int read()
  11. {
  12. char ch=getchar(); int f=1,w=0;
  13. while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
  14. while(ch<='9'&&ch>='0'){w=w*10+ch-'0';ch=getchar();}
  15. return f*w;
  16. }
  17. void floyd()
  18. {
  19. for(int p=1;p<=20;p++)
  20. for(int k=1;k<=cnt;k++)
  21. for(int i=1;i<=cnt;i++)
  22. for(int j=1;j<=cnt;j++)
  23. dis[i][j][p]=min(dis[i][j][p],dis[i][k][p-1]+dis[k][j][p-1]);
  24. }
  25. void getans()
  26. {
  27. memset(ans,127/2,sizeof(ans));
  28. int t=0,p=0;
  29. ans[0][S]=0;
  30. while(n)
  31. {
  32. if(n&1)
  33. {
  34. t=!t;
  35. for(int i=1;i<=cnt;i++)
  36. {
  37. ans[t][i]=2e9;
  38. for(int j=1;j<=cnt;j++)
  39. ans[t][i]=min(ans[t][i],ans[!t][j]+dis[i][j][p]);
  40. }
  41. }
  42. p++; n/=2;
  43. }
  44. cout<<ans[t][E];
  45. }
  46. #include<bits/stdc++.h>
  47. using namespace std;
  48. const int maxn=10008;
  49. struct node{int u,k;};
  50. int cnt;
  51. int x[maxn],y[maxn],w[maxn];
  52. int to[maxn],num,n,t,S,E;
  53. int dis[508][508][22],ans[508][508];
  54. map<int,int>kkk;
  55. int read()
  56. {
  57. char ch=getchar(); int f=1,w=0;
  58. while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
  59. while(ch<='9'&&ch>='0'){w=w*10+ch-'0';ch=getchar();}
  60. return f*w;
  61. }
  62. void floyd()
  63. {
  64. for(int p=1;p<=20;p++)
  65. for(int k=1;k<=cnt;k++)
  66. for(int i=1;i<=cnt;i++)
  67. for(int j=1;j<=cnt;j++)
  68. dis[i][j][p]=min(dis[i][j][p],dis[i][k][p-1]+dis[k][j][p-1]);
  69. }
  70. void getans()
  71. {
  72. memset(ans,127/2,sizeof(ans));
  73. int t=0,p=0;
  74. ans[0][S]=0;
  75. while(n)
  76. {
  77. if(n&1)
  78. {
  79. t=!t;
  80. for(int i=1;i<=cnt;i++)
  81. {
  82. ans[t][i]=2e9;
  83. for(int j=1;j<=cnt;j++)
  84. ans[t][i]=min(ans[t][i],ans[!t][j]+dis[i][j][p]);
  85. }
  86. }
  87. p++; n/=2;
  88. }
  89. cout<<ans[t][E];
  90. }
  91. void pre()
  92. {
  93. sort(to+1,to+num+1);
  94. int last=192608173;
  95. for(int i=1;i<=num;i++)
  96. {
  97. if(to[i]!=last)
  98. {
  99. kkk[to[i]]=++cnt;
  100. last=to[i];
  101. }
  102. }
  103. for(int i=1;i<=t;i++)
  104. {
  105. x[i]=kkk[x[i]],y[i]=kkk[y[i]];
  106. dis[x[i]][y[i]][0]=dis[y[i]][x[i]][0]=w[i];
  107. }
  108. }
  109. int main()
  110. {
  111. n=read(); t=read(); S=read(); E=read();
  112. memset(dis,127/3,sizeof(dis));
  113. for(int i=1;i<=t;i++)
  114. {
  115. w[i]=read();
  116. x[i]=read(); y[i]=read();
  117. to[++num]=x[i]; to[++num]=y[i];
  118. }
  119. pre(); S=kkk[S],E=kkk[E];
  120. floyd();
  121. getans();
  122. }
  123. void pre()
  124. {
  125. sort(to+1,to+num+1);
  126. int last=192608173;
  127. for(int i=1;i<=num;i++)
  128. {
  129. if(to[i]!=last)
  130. {
  131. kkk[to[i]]=++cnt;
  132. last=to[i];
  133. }
  134. }
  135. for(int i=1;i<=t;i++)
  136. {
  137. x[i]=kkk[x[i]],y[i]=kkk[y[i]];
  138. dis[x[i]][y[i]][0]=dis[y[i]][x[i]][0]=w[i];
  139. }
  140. }
  141. int main()
  142. {
  143. n=read(); t=read(); S=read(); E=read();
  144. memset(dis,127/3,sizeof(dis));
  145. for(int i=1;i<=t;i++)
  146. {
  147. w[i]=read();
  148. x[i]=read(); y[i]=read();
  149. to[++num]=x[i]; to[++num]=y[i];
  150. }
  151. pre(); S=kkk[S],E=kkk[E];
  152. floyd();
  153. getans();
  154. }

[USACO07NOV]牛继电器Cow Relays (最短路,DP)的更多相关文章

  1. [USACO07NOV]牛继电器Cow Relays

    题目描述 给出一张无向连通图,求S到E经过k条边的最短路. 输入输出样例 输入样例#1: 2 6 6 4 11 4 6 4 4 8 8 4 9 6 6 8 2 6 9 3 8 9 输出样例#1: 10 ...

  2. P2886 [USACO07NOV]牛继电器Cow Relays

    题目描述 For their physical fitness program, N (2 ≤ N ≤ 1,000,000) cows have decided to run a relay race ...

  3. 洛谷P2886 [USACO07NOV]牛继电器Cow Relays

    题意很简单,给一张图,把基本的求起点到终点最短路改成求经过k条边的最短路. 求最短路常用的算法是dijkstra,SPFA,还有floyd. 考虑floyd的过程: c[i][j]=min(c[i][ ...

  4. Luogu 2886 [USACO07NOV]牛继电器Cow Relays

    BZOJ 1706权限题. 倍增$floyd$. 首先这道题有用的点最多只有$200$个,先离散化. 设$f_{p, i, j}$表示经过$2^p$条边从$i$到$j$的最短路,那么有转移$f_{p, ...

  5. [LUOGU] P2886 [USACO07NOV]牛继电器Cow Relays

    https://www.luogu.org/problemnew/show/P2886 给定无向连通图,求经过k条边,s到t的最短路 Floyd形式的矩阵乘法,同样满足结合律,所以可以进行快速幂. 离 ...

  6. [luoguP2886] [USACO07NOV]牛继电器Cow Relays(矩阵)

    传送门 矩阵快速幂,本质是floyd 把 * 改成 + 即可 注意初始化 因为只有100条边,所以可以离散化 #include <cstdio> #include <cstring& ...

  7. 洛谷 P2886 [USACO07NOV]牛继电器Cow Relays

    题面 解题思路 ## floyd+矩阵快速幂,跟GhostCai爷打赌用不用离散化,最后完败..GhostCai真是tql ! 有个巧妙的方法就是将节点重新编号,因为与节点无关. 代码 #includ ...

  8. luogu题解 P2886 【牛继电器Cow Relays】-经过K边最短路&矩阵

    题目链接: https://www.luogu.org/problemnew/show/P2886 Update 6.16 最近看了下<算法导论>,惊奇地发现在在介绍\(APSP\) \( ...

  9. [洛谷P2886] 牛继电器Cow Relays

    问题描述 For their physical fitness program, N (2 ≤ N ≤ 1,000,000) cows have decided to run a relay race ...

随机推荐

  1. SG函数入门&&HDU 1848

    SG函数 sg[i]为0表示i节点先手必败. 首先定义mex(minimal excludant)运算,这是施加于一个集合的运算,表示最小的不属于这个集合的非负整数.例如mex{0,1,2,4}=3. ...

  2. stixel world论文总结

    1.The Stixel World - A Compact Medium Level Representation of the 3D-World:http://pdfs.semanticschol ...

  3. PropertyConfigurer.java

    package util; import java.util.Properties; import org.springframework.beans.BeansException; import o ...

  4. 安全错误使用CORS在IE10与Node和Express及XMLHttpRequest: 网络错误 0x4c7, 操作已被用户取消

    在IE下:VUE项目,后台替换为https请求之后,vue热更新请求挂起,控制台报错:XMLHttpRequest: 网络错误 0x4c7, 操作已被用户取消.但是chrome与Firefox正常 当 ...

  5. 201621123080《java程序设计》第14周实验总结

    201621123080<java程序设计>第14周实验总结 1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结与数据库相关内容. 2. 使用数据库技术改造你的系统 2. ...

  6. Qt概念和快捷键

    Qt概念和快捷键 Qt简介        1.Qt的由来和发展 Qt是一个1991年由Qt Company开发的跨平台C++图形用户界面应用程序开发框架.它既可以开发GUI程序,也可用于开发非GUI程 ...

  7. LeetCode之Weekly Contest 90

    LeetCode第90场周赛记录 第一题:亲密字符串 问题: 给定两个由小写字母构成的字符串 A 和 B ,只要我们可以通过交换 A 中的两个字母得到与 B 相等的结果,就返回 true :否则返回  ...

  8. 如何用纯 CSS 和 D3 创作一只扭动的蠕虫

    效果预览 在线演示 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/QBQJMg 可交互视频 ...

  9. 【php】 phpword下载文件问题

    这个问题是在 科锐国际 工作过程中发现的 word文档的名字(有汉字和空格)在windows系统上遍历是查不到文件的,但是在linux系统上市可以的压缩包里面的中文名word文档,如果出现汉字和空格, ...

  10. Python语言的简介

    ___________________________________________________________我是一条分割线__________________________________ ...