Magical Girl Haze 分层图最短路

发布时间:2019年07月22日 阅读:300 次

C++
  1. 题目链接:https://nanti.jisuanke.com/t/A1958
  2. 原题目:https://acm.taifua.com/bzoj/p/2763.html
  3. 题意:n 个点 m 条有向边,可以让其中不超过 k 条边的边权为 0,问从 1 到 n 的最短路径。
  4. https://blog.csdn.net/axuhongbo/article/details/82289535
  5. 分层图最短路,把图拆成k+1层,然后每个点拆成k+1个点,这样就有1e6个点,对着1e6个点进行最短路的计算,
  6. 堆优化的Dijkstra,O(m+n)logn,大概是1e7的时间复杂度是可以过的!
  7. 我们把每个点都拆成k个层次点,每个相同层次的点按输入的边权连接,每个点可以向它能连接到的点的
  8. 下一个层次连接一条边权为0的边;
  9. #include<iostream>
  10. #include<cstdio>
  11. #include<cmath>
  12. #include<cstring>
  13. #include<algorithm>
  14. #include<queue>
  15. using namespace std;
  16. int n,m,k;
  17. int head[3200000],tot;
  18. long long dis[3200000];
  19. struct node{
  20. int u,v,w,nxt;
  21. }edge[3200000*2];
  22. int vis[3000000];
  23. void addedge(int u,int v,int w){
  24. edge[tot].u=u;
  25. edge[tot].v=v;
  26. edge[tot].w=w;
  27. edge[tot].nxt=head[u];
  28. head[u]=tot++;
  29. }
  30. struct node2{
  31. int u;
  32. long long dis;
  33. bool operator < (node2 b) const{
  34. return dis>b.dis;
  35. }
  36. };
  37. void dij(int x){
  38. dis[x]=0;
  39. priority_queue<node2> s;
  40. node2 c;
  41. c.u=x;
  42. c.dis=dis[x];
  43. memset(vis,0,sizeof vis);
  44. s.push(c);
  45. while(!s.empty()){
  46. c=s.top();
  47. s.pop();
  48. if(vis[c.u])continue;
  49. vis[c.u] = 1;
  50. for(int i=head[c.u];~i;i=edge[i].nxt){
  51. int v=edge[i].v;
  52. int w=edge[i].w;
  53. if(dis[v]>dis[c.u]+w){
  54. dis[v]=dis[c.u]+w;
  55. node2 e;
  56. e.u=v;
  57. e.dis=dis[v];
  58. s.push(e);
  59. }
  60. }
  61. }
  62. }
  63. int main(){
  64. int T;
  65. scanf("%d",&T);
  66. while(T--){
  67. scanf("%d%d%d",&n,&m,&k);
  68. memset(dis,0x7f7f7f7f,sizeof dis);
  69. memset(head,-1,sizeof head);
  70. tot=0;
  71. for(int i=1;i<=m;i++){
  72. // int
  73. long long u,v,w;
  74. scanf("%lld %lld %lld",&u,&v,&w);
  75. for(int j=0;j<=k;j++){
  76. addedge(u+n*j,v+n*j,w);
  77. //addedge(v+n*j,u+n*j,w);
  78. if(j!=k)
  79. addedge(u+n*j,v+n*(j+1),0);
  80. }
  81. // for(int j=0;j<=k-1;j++)
  82. }
  83. dij(1);
  84. // for(int i=1;i<=tot;i++){
  85. // cout<<edge[i].v<<" "<<edge[i].w<<" "<<edge[i].nxt<<endl;
  86. // }
  87. long long maxn=0x3f3f3f3f;
  88. for(int i=0;i<=k;i++){
  89. // cout<<"*";
  90. // cout<<dis[i*n+n]<<" ";
  91. maxn = min(maxn,dis[i*n+n]);
  92. }
  93. //cout<<endl;
  94. printf("%lld\n",maxn);
  95. }
  96. return 0;
  97. }


Tag:
相关文章

发表评论: