题意与分析

题意是这样的,定义一个从某点出发的所有最短路方案中,选择边权和最小的最短路方案,称为最短生成树

现在求一棵最短生成树,输出总边权和与选取边的编号。

我们首先要明白这样一个结论:对一个图求Dijkstra后,把所有得到的最短路边全部连起来,生成的图一定是一棵树,是不会有环的。原因自己推一下就可以感受到。

那么这样一来,这个树相当于我们在Dijkstra的时候就已经得到了。记录边是Dijkstra的基本操作,而我们只需要考虑一下当最短路相等时谁更优的情况并更新就可以了。

代码

  1. #include <bits/stdc++.h>
  2. #define MP make_pair
  3. #define PB emplace_back
  4. #define fi first
  5. #define se second
  6. #define ZERO(x) memset((x), 0, sizeof(x))
  7. #define ALL(x) (x).begin(),(x).end()
  8. #define rep(i, a, b) for (repType i = (a); i <= (b); ++i)
  9. #define per(i, a, b) for (repType i = (a); i >= (b); --i)
  10. #define QUICKIO \
  11. ios::sync_with_stdio(false); \
  12. cin.tie(0); \
  13. cout.tie(0);
  14. using namespace std;
  15. using ll=long long;
  16. using repType=int;
  17. struct Edge
  18. {
  19. int u, v;
  20. ll w;
  21. Edge() {}
  22. Edge(int _u, int _v, ll _w): u(_u), v(_v), w(_w) {}
  23. bool
  24. operator < (const Edge& rhs) const
  25. {
  26. if(w==rhs.w)
  27. { return (u==rhs.u)?v<rhs.v:u<rhs.u; }
  28. else { return w<rhs.w; }
  29. }
  30. };
  31. const int MAXN=300005;
  32. vector<Edge> edges;
  33. vector<int> G[MAXN];
  34. void
  35. add_edge(int u, int v, ll w)
  36. {
  37. edges.PB(u, v, w);
  38. G[u].PB(int(edges.size())-1);
  39. }
  40. ll dist[MAXN];
  41. int pre[MAXN]; // pre: last edge
  42. void
  43. dijkstra(int start)
  44. {
  45. memset(pre, -1, sizeof(pre));
  46. memset(dist, 0x3f, sizeof(dist));
  47. using P=pair<ll, int>;
  48. priority_queue<P, vector<P>, greater<> > pq; // <dist, pnt>: 大根堆
  49. dist[start]=0;
  50. pq.push(MP(0, start));
  51. while(!pq.empty())
  52. {
  53. auto now=pq.top(); pq.pop();
  54. int u=now.se;
  55. if(dist[u]<now.fi) { continue; }
  56. rep(i, 0, int(G[u].size())-1)
  57. {
  58. int v=edges[G[u][i]].v;
  59. ll w=edges[G[u][i]].w;
  60. if(dist[v]>dist[u]+w)
  61. {
  62. dist[v]=dist[u]+w;
  63. pre[v]=G[u][i];
  64. pq.push(MP(dist[v], v));
  65. }
  66. else if(dist[v]==dist[u]+w && edges[pre[v]].w>edges[G[u][i]].w)
  67. { pre[v]=G[u][i]; }
  68. }
  69. }
  70. }
  71. int
  72. main()
  73. {
  74. int n, m;
  75. scanf("%d%d", &n, &m);
  76. rep(i, 1, m)
  77. {
  78. int u, v;
  79. ll w;
  80. scanf("%d%d%lld", &u, &v, &w);
  81. add_edge(u, v, w);
  82. add_edge(v, u, w);
  83. }
  84. int stp; scanf("%d", &stp);
  85. dijkstra(stp);
  86. ll ans=0;
  87. rep(i, 1, n) if(i!=stp) { ans+=edges[pre[i]].w; }
  88. printf("%lld\n", ans);
  89. rep(i, 1, n) if(i!=stp) { printf("%d ", pre[i]/2+1); }
  90. printf("\n");
  91. return 0;
  92. }

「日常训练」Paths and Trees(Codeforces Round 301 Div.2 E)的更多相关文章

  1. 「日常训练」Ice Cave(Codeforces Round 301 Div.2 C)

    题意与分析(CodeForces 540C) 这题坑惨了我....我和一道经典的bfs题混淆了,这题比那题简单. 那题大概是这样的,一个冰塔,第一次踩某块会碎,第二次踩碎的会掉落.然后求可行解. 但是 ...

  2. 「日常训练」School Marks(Codeforces Round 301 Div.2 B)

    题意与分析(CodeForces 540B) 题意大概是这样的,有一个考试鬼才能够随心所欲的控制自己的考试分数,但是有两个限制,第一总分不能超过一个数,不然就会被班里学生群嘲:第二分数的中位数(科目数 ...

  3. 「日常训练」Watering Flowers(Codeforces Round #340 Div.2 C)

    题意与分析 (CodeForces 617C) 题意是这样的:一个花圃中有若干花和两个喷泉,你可以调节水的压力使得两个喷泉各自分别以\(r_1\)和\(r_2\)为最远距离向外喷水.你需要调整\(r_ ...

  4. 「日常训练」Alternative Thinking(Codeforces Round #334 Div.2 C)

    题意与分析 (CodeForces - 603A) 这题真的做的我头疼的不得了,各种构造样例去分析性质... 题意是这样的:给出01字符串.可以在这个字符串中选择一个起点和一个终点使得这个连续区间内所 ...

  5. 「日常训练」More Cowbell(Codeforces Round #334 Div.2 B)

    题意与分析(CodeForces 604B) 题意是这样的:\(n\)个数字,\(k\)个盒子,把\(n\)个数放入\(k\)个盒子中,每个盒子最多只能放两个数字,问盒子容量的最小值是多少(水题) 不 ...

  6. 「日常训练」The Intriguing Obsession(CodeForces Round #439 Div.2 C)

    2018年11月30日更新,补充了一些思考. 题意(CodeForces 869C) 三堆点,每堆一种颜色:连接的要求是同色不能相邻或距离必须至少3.问对整个图有几种连接方法,对一个数取模. 解析 要 ...

  7. 「日常训练」Regular Bridge(Codeforces Round 306 Div.2 D)

    题意与分析 图论基础+思维题. 代码 #include <bits/stdc++.h> #define MP make_pair #define PB emplace_back #defi ...

  8. 「日常训练」Two Substrings(Codeforces Round 306 Div.2 A)

    题意与分析 一道非常坑的水题.分析醒了补. 代码 #include <bits/stdc++.h> #define MP make_pair #define PB emplace_back ...

  9. 「专题训练」Hard problem(Codeforces Round #367 Div. 2 C)

    题意与分析 题意:给出\(n\)个字符串,可以反转任意串,反转每个串都有其对应的花费\(c_i\).经过操作后是否能满足字符串\(\forall i \in [1,n] \text{且} i \in ...

随机推荐

  1. Vue点击切换class

    <style> .active{ color: red; } </style> <ul id="app"> <li v-for='(ite ...

  2. 11、SpringBoot-CRUD-thymeleaf公共页面元素抽取

    thymeleaf公共页面元素抽取 存在一种现象:两个文件的代码只有一部分代码不一样 其余的均相同,此时就可以提取公共的代码去简化开发 .抽取公共片段 <div th:fragment=&quo ...

  3. Windows平台JxCore打包

    1.下载JxCore https://raw.githubusercontent.com/jxcore/jxcore-release/master/0311/jx_win64v8.zip 2.解压并配 ...

  4. jenkins没安装git报错

    Jenkins新建项目中源码管理使用Git时遇到如下问题: 在安装jenkins服务器上查看一下git版本,可能没有安装git  也可能是git版本太低 [root@localhost nnnnn]# ...

  5. 国产Linux下开发正式开工(deepin)

    配置开发环境 1.一般工具 在深度商店安装QQ,微信,安装一般软件WPS,Navicat数据库工具,文本编辑notepadqq. 影视娱乐爱奇艺,优酷,酷狗. 2.安装主要的开发环境 (1)c# 深度 ...

  6. 将jquery.qqFace.js表情转换成微信的字符码

    jquery.qqFace.js使用方法 引用 <script src="~/Content/qqFace/js/jquery.qqFace.js?v=3"></ ...

  7. 关于端口冲突的解决方式Error: listen EACCES 0.0.0.80

    笔者昨天下午临走前安装了vs 2017想要运行一下项目的NET后端来让本机的前端直接对接后端,但是没注意到运行vs后IIS直接占用了本机的80端口.第二天跑nodeJS的时候直接Error: list ...

  8. 小K的农场(差分约束,spfa)

    题目描述 小K在MC里面建立很多很多的农场,总共n个,以至于他自己都忘记了每个农场中种植作物的具体数量了,他只记得一些含糊的信息(共m个),以下列三种形式描述: 农场a比农场b至少多种植了c个单位的作 ...

  9. .net core 基于Claim登录验证

    网站,首先需要安全,实现安全就必须使用登录验证,.net core 基于Claim登录验证就很简单使用. Claim是什么,可以理解为你的身份证的中的名字,性别等等的每一条信息,然后Claim组成一个 ...

  10. cut 的用法

    cut 文件内容查看 显示行中的指定部分,删除文件中指定字段 显示文件的内容,类似于下的type命令. 说明 该命令有两项功能,其一是用来显示文件的内容,它依次读取由参数file所指明的文件,将它们的 ...