前言

本来在比赛上就想到最小生成树了,但不相信这道题那么简单,然后就没有然后了。。。

题目

给出一幅由n个点m条边构成的无向带权图。

其中有些点是黑点,其他点是白点。

现在每个白点都要与他距离最近的黑点通过最短路连接(如果有很多个黑点,可以选取其中任意一个),我们想要使得花费的代价最小。请问这个最小代价是多少?

注意:最后选出的边保证每个白点到离它最近的黑点的距离仍然等于原图中的最短距离。

分析

  1. 这道题最麻烦的地方就是最终搞成的图有可能有很多个联通块。

增加一个点:0点,让0点连接所有的黑点,边权为0;

处理从S发到每个点的最短距离

题目要求最小的总距离,显然搞一遍最小生成树就可以了。

  1. #include <cmath>
  2. #include <iostream>
  3. #include <cstdio>
  4. #include <cstdlib>
  5. #include <cstring>
  6. #include <algorithm>
  7. #include <queue>
  8. const long long maxlongint=2147483747;
  9. using namespace std;
  10. long long b[710000][4],dis[710000],next[710000],last[710000],a[710000],fa[710000],ans,tot,n,m,v[710000],d[8000000];
  11. bool bz[710000];
  12. void q(long long l,long long r)
  13. {
  14. long long i=l,j=r;
  15. long long mid=b[(l+r)/2][0],e;
  16. while(i<j)
  17. {
  18. while(b[i][0]<mid) i++;
  19. while(b[j][0]>mid) j--;
  20. if(i<=j)
  21. {
  22. e=b[i][0];
  23. b[i][0]=b[j][0];
  24. b[j][0]=e;
  25. e=b[i][1];
  26. b[i][1]=b[j][1];
  27. b[j][1]=e;
  28. e=b[i][2];
  29. b[i][2]=b[j][2];
  30. b[j][2]=e;
  31. i++;
  32. j--;
  33. }
  34. }
  35. if(i<r) q(i,r);
  36. if(l<j) q(l,j);
  37. }
  38. int spfa()
  39. {
  40. long long head=0,tail=1,k;
  41. fill(dis,dis+n+m+1,maxlongint*3);
  42. fill(bz,bz+n+m+1,true);
  43. d[1]=0;
  44. dis[0]=0;
  45. while(head<tail)
  46. {
  47. k=d[++head];
  48. bz[k]=true;
  49. for(long long i=last[k];i;i=next[i])
  50. {
  51. if(dis[a[i]]>dis[k]+v[i])
  52. {
  53. dis[a[i]]=dis[k]+v[i];
  54. if(bz[a[i]])
  55. {
  56. d[++tail]=a[i];
  57. bz[a[i]]=false;
  58. }
  59. }
  60. }
  61. }
  62. }
  63. bool dg(long long x)
  64. {
  65. long long i,j;
  66. for(i=last[x];i;i=next[i])
  67. {
  68. long long y=a[i];
  69. if(dis[x]+v[i]==dis[y])
  70. {
  71. dg(y);
  72. b[++tot][1]=x;
  73. b[tot][2]=y;
  74. b[tot][0]=v[i];
  75. }
  76. }
  77. return true;
  78. }
  79. long long get(long long x)
  80. {
  81. if(x==fa[x]) return x;
  82. long long y=get(fa[x]);
  83. fa[x]=y;
  84. return y;
  85. }
  86. int kruskal()
  87. {
  88. long long i,j,k,l,x,y;
  89. for(i=1;i<=tot;i++)
  90. {
  91. x=get(b[i][1]);
  92. y=get(b[i][2]);
  93. if(x!=y)
  94. {
  95. ans+=b[i][0];
  96. fa[y]=x;
  97. }
  98. }
  99. }
  100. int bj(long long x,long long y,long long k)
  101. {
  102. fa[y]=y;
  103. next[++tot]=last[x];
  104. last[x]=tot;
  105. v[tot]=k;
  106. a[tot]=y;
  107. }
  108. int main()
  109. {
  110. scanf("%lld%lld",&n,&m);
  111. long long i,j,k,l,x,y;
  112. for(i=1;i<=n;i++)
  113. {
  114. scanf("%lld",&x);
  115. if(x) bj(0,i,0);
  116. }
  117. for(i=1;i<=m;i++)
  118. {
  119. scanf("%lld%lld%lld",&x,&y,&k);
  120. bj(x,y,k);
  121. bj(y,x,k);
  122. }
  123. spfa();
  124. tot=0;
  125. dg(0);
  126. q(1,tot);
  127. bool b1=maxlongint;
  128. kruskal();
  129. if(ans==0) cout<<"impossible";else
  130. cout<<ans;
  131. }

【NOIP2015模拟10.22】最小代价的更多相关文章

  1. [NOIP2015模拟10.22] 最小代价 解题报告 (最小生成树)

    Description 给出一幅由n个点m条边构成的无向带权图.其中有些点是黑点,其他点是白点.现在每个白点都要与他距离最近的黑点通过最短路连接(如果有很多个黑点,可以选取其中任意一个),我们想要使得 ...

  2. [NOIP2015模拟10.22] 最大子矩阵 解题报告(单调栈)

    Description 我们将矩阵A中位于第i行第j列的元素记作A[i,j].一个矩阵A是酷的仅当它满足下面的条件:       A[1,1]+A[r,s]<=A[1,s]+A[r,1](r,s ...

  3. JZOJ 4273. 【NOIP2015模拟10.28B组】圣章-精灵使的魔法语

    4273. [NOIP2015模拟10.28B组]圣章-精灵使的魔法语 (File IO): input:elf.in output:elf.out Time Limits: 1000 ms  Mem ...

  4. JZOJ 4269. 【NOIP2015模拟10.27】挑竹签

    4269. [NOIP2015模拟10.27]挑竹签 (File IO): input:mikado.in output:mikado.out Time Limits: 1000 ms  Memory ...

  5. JZOJ 4272. 【NOIP2015模拟10.28B组】序章-弗兰德的秘密

    272. [NOIP2015模拟10.28B组]序章-弗兰德的秘密 (File IO): input:frand.in output:frand.out Time Limits: 1000 ms  M ...

  6. [jzoj]4271. 【NOIP2015模拟10.27】魔法阵(37种转移的dp)

    题意不说 应该这辈子都不会忘记了... 这是我人生中做的最SB的一道DP题. 真的打的我心态崩了.... 可是竟然被我调出来了..... 也是没谁了... 我们设\(F[i][j][S]\)表示到第\ ...

  7. [JZOJ4272] [NOIP2015模拟10.28B组] 序章-弗兰德的秘密 解题报告(树形DP)

    Description 背景介绍弗兰德,我不知道这个地方对我意味着什么.这里是一切开始的地方.3年前,还是个什么都没见过的少年,来到弗兰德的树下,走进了封闭的密室,扭动的封尘已久机关,在石板上知道了这 ...

  8. [NOIP2015模拟10.27] 挑竹签 解题报告(拓扑排序)

    Description 挑竹签——小时候的游戏夏夜,早苗和诹访子在月光下玩起了挑竹签这一经典的游戏.挑竹签,就是在桌上摆上一把竹签,每次从最上层挑走一根竹签.如果动了其他的竹签,就要换对手来挑.在所有 ...

  9. [NOIP2015模拟10.27] [JZOJ4270] 魔道研究 解题报告(动态开点+权值线段树上二分)

    Description “我希望能使用更多的魔法.不对,是预定能使用啦.最终我要被大家称呼为大魔法使.为此我决定不惜一切努力.”——<The Grimoire of Marisa>雾雨魔理 ...

随机推荐

  1. 使用 go protoc --go_out 输出的 *.pb.go文件时报 undefined: proto.ProtoPackageIsVersion3

    事情是这样的:我参考go的 grpc 实现 https://grpc.io/docs/quickstart/go/ Download the example The grpc code that wa ...

  2. 【js】什么是函数节流与函数去抖

    函数节流 意思:节省流量,不会一直访问. | 指定时间内不执行,指定时间后执行. | 一段时间内只执行一次 场景: 比如控制游戏人物攻击,时间内就算按得很快,也只能砍一刀,过后才能砍第二刀. 搜索引擎 ...

  3. Eclipse 添加 UML Model插件

    1.下载安装 ModelGson 下载链接:https://pan.baidu.com/s/1smIZApv   密码:mu5l eclipse安装ModelGson(注意不用解压ModelGson, ...

  4. 【ABAP系列】SAP 系统的消息类型分析 MESSAGE TYPE

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[ABAP系列]SAP 系统的消息类型分析 ME ...

  5. [LeetCode] 1090. Largest Values From Labels

    使用 Java 爬取 LeetCode 题目内容以及提交的AC代码 传送门 Description We have a set of items: the i-th item has value va ...

  6. 【Linux 环境搭建】ubuntu下nfs安装与配置

    (1)安装 #sudo apt-get install nfs-kernel-server portmap(2)修改配置文件 修改/etc/exports,增加以下内容, /root/wksp/roo ...

  7. Android的Monkey和MonkeyRunner

    本文部分解释性语段摘自网络百科或其它BLOG,语句内容网络随处可见,也不知道谁是初始原创,便不再署名出处,如有雷同,还请见谅. Monkey 什么是Monkey Monkey是Android中的一个命 ...

  8. Java内存结构详解

    Java内存结构详解 Java把内存分成:栈内存,堆内存,方法区,本地方法区和寄存器等. 下面分别介绍栈内存,堆内存,方法区各自一些特性: 1.栈内存 (1)一些基本类型的变量和对象的引用变量都是在函 ...

  9. C++中的字符串类

    1,本文分析 C++ 中的字符串,C 语言中的字符串利用的是 C 语言中的字符数组,  在 C 语言中没有真正意义上的字符串,利用了字符数组表示了字符串,最初设  计 C 语言仅仅是为了开发 Unix ...

  10. Linear Discriminant Analysis

    Suppose that we model each class density as multivariate Gaussian, in practice we do not know the pa ...