题意:给你n(n = 1000)个二维点,第一个点是power plant,还有n - 1个点是dormitories。然后现在知道有一条寝室到寝室的边是不能连的,但是我们不知道是哪条边,问这种情况下,最小生成树的最大值。

好题,毕竟做了一下午,注意dis要double转换

dfs求的是从cur点出发到以u为根的树的最小距离,可以是树根,也可以是树的子节点

枚举的边一定是在最小生成树上的,这个边被删除后,我们需要重新建立一条边来替代它,因此需要dfs来求

  1. #include<cstdio>
  2. #include<iostream>
  3. #include<algorithm>
  4. #include<cstring>
  5. #include<cmath>
  6. #include<queue>
  7. #include<map>
  8. using namespace std;
  9. #define MOD 1000000007
  10. const int INF=0x3f3f3f3f;
  11. const double eps=1e-;
  12. typedef long long ll;
  13. #define cl(a) memset(a,0,sizeof(a))
  14. #define ts printf("*****\n");
  15. const int MAXN=;
  16. int n,m,tt;
  17. /*
  18. * Kruskal算法求MST
  19. */
  20. const int MAXM=;//最大边数
  21. int tol;//边数,加边前赋值为0
  22. struct Edge
  23. {
  24. int to,next;
  25. }edge[MAXM];
  26. int head[MAXN],tot;
  27. void init()
  28. {
  29. tot = ;
  30. memset(head,-,sizeof(head));
  31. }
  32. void addedge(int u,int v)
  33. {
  34. edge[tot].to = v; edge[tot].next = head[u];
  35. head[u] = tot++;
  36. }
  37. bool mp[MAXN][MAXN];
  38. double dp[MAXN][MAXN];
  39. /*
  40. * Prim求MST
  41. * 耗费矩阵cost[][],标号从0开始,0~n-1
  42. * 返回最小生成树的权值,返回-1表示原图不连通
  43. */
  44. int vis[MAXN];
  45. double lowc[MAXN];
  46. double Prim(double cost[][MAXN],int n)//点是0~n-1
  47. {
  48. double ans=;
  49. memset(vis,false,sizeof(vis));
  50. vis[]=-;
  51. int last[MAXN];
  52. last[]=;
  53. for(int i=;i<n;i++)lowc[i]=cost[][i];
  54. for(int i=;i<n;i++)
  55. {
  56. double minc=INF;
  57. int p=-;
  58. for(int j=;j<n;j++)
  59. if(vis[j]!=-&&minc>lowc[j])
  60. {
  61. minc=lowc[j];
  62. p=j;
  63. }
  64. if(minc==INF)return -;//原图不连通
  65. mp[vis[p]][p]=mp[p][vis[p]]=;
  66. addedge(vis[p],p);
  67. addedge(p,vis[p]);
  68. ans+=minc;
  69. vis[p]=-;
  70. for(int j=;j<n;j++)
  71. if(vis[j]!=-&&lowc[j]>cost[p][j])
  72. {
  73. vis[j]=p;
  74. lowc[j]=cost[p][j];
  75. }
  76. }
  77. return ans;
  78. }
  79. int x[MAXN],y[MAXN];
  80. double dist[MAXN][MAXN];
  81. double dis(int i,int j)
  82. {
  83. return sqrt((double)(x[i]-x[j])*(double)(x[i]-x[j])+(double)(y[i]-y[j])*(double)(y[i]-y[j]));
  84. }
  85. double dfs(int cur,int u,int fa){
  86. double res=(double)INF;
  87. for(int i=head[u];i!=-;i=edge[i].next){
  88. int v=edge[i].to;
  89. if(v==fa)continue;
  90. double tmp=dfs(cur,v,u);
  91. dp[u][v]=dp[v][u]=min(tmp,dp[u][v]);
  92. res=min(res,tmp);
  93. }
  94. if(fa!=cur){
  95. res=min(res,dist[cur][u]);
  96. }
  97. return res;
  98. }
  99. int main()
  100. {
  101. int i,j,k,ca=;
  102. #ifndef ONLINE_JUDGE
  103. freopen("1.in","r",stdin);
  104. #endif
  105. scanf("%d",&tt);
  106. int val;
  107. while(tt--)
  108. {
  109. init();
  110. tol=;
  111. scanf("%d%d",&n,&val);
  112. cl(dist);
  113. for(i=;i<n;i++)
  114. {
  115. scanf("%d%d",x+i,y+i);
  116. }
  117. for(i=;i<n;i++)
  118. {
  119. for(j=;j<n;j++)
  120. {
  121. dist[i][j]=dist[j][i]=dis(i,j);
  122. }
  123. }
  124. cl(mp);
  125. double sumw=Prim(dist,n);
  126. double Max=sumw;
  127. for(int i=;i<n;i++)
  128. for(int j=i;j<n;j++)
  129. dp[i][j]=dp[j][i]=(double)INF;
  130. for(i=;i<n;i++)
  131. {
  132. dfs(i,i,-);
  133. }
  134. for(i=;i<n;i++) //枚举每条边
  135. {
  136. for(j=i+;j<n;j++)
  137. {
  138. if(mp[i][j]) Max=max(Max,sumw-dist[i][j]+dp[i][j]);
  139. }
  140. }
  141. printf("%.2lf\n",Max*val);
  142. }
  143. }

hdu 4756 MST+树形dp ****的更多相关文章

  1. hdu4756 Install Air Conditioning(MST + 树形DP)

    题目请戳这里 题目大意:给n个点,现在要使这n个点连通,并且要求代价最小.现在有2个点之间不能直接连通(除了第一个点),求最小代价. 题目分析:跟这题一样样的,唉,又是原题..先求mst,然后枚举边, ...

  2. HDU 2196.Computer 树形dp 树的直径

    Computer Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

  3. HDU 2196 Computer 树形DP经典题

    链接:http://acm.hdu.edu.cn/showproblem.php? pid=2196 题意:每一个电脑都用线连接到了还有一台电脑,连接用的线有一定的长度,最后把全部电脑连成了一棵树,问 ...

  4. hdu 6201 【树形dp||SPFA最长路】

    http://acm.hdu.edu.cn/showproblem.php?pid=6201 n个城市都在卖一种书,该书的价格在i城市为cost[i],商人打算从某个城市出发到另一个城市结束,途中可以 ...

  5. HDU 2196 Computer 树形DP 经典题

    给出一棵树,边有权值,求出离每一个节点最远的点的距离 树形DP,经典题 本来这道题是无根树,可以随意选择root, 但是根据输入数据的方式,选择root=1明显可以方便很多. 我们先把边权转化为点权, ...

  6. hdu 4081 最小生成树+树形dp

    思路:直接先求一下最小生成树,然后用树形dp来求最优值.也就是两遍dfs. #include<iostream> #include<algorithm> #include< ...

  7. HDU 3899 简单树形DP

    题意:一棵树,给出每个点的权值和每条边的长度, 点j到点i的代价为点j的权值乘以连接i和j的边的长度.求点x使得所有点到点x的代价最小,输出 虽然还是不太懂树形DP是什么意思,先把代码贴出来把. 这道 ...

  8. HDU 4714 Tree2cycle (树形DP)

    题意:给定一棵树,断开一条边或者接上一条边都要花费 1,问你花费最少把这棵树就成一个环. 析:树形DP,想一想,要想把一棵树变成一个环,那么就要把一些枝枝叶叶都换掉,对于一个分叉是大于等于2的我们一定 ...

  9. hdu Anniversary party 树形DP,点带有值。求MAX

    Anniversary party Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others ...

随机推荐

  1. 统计代码git提交的行数

    $ git log --author="$(git config --get user.name)" --pretty=tformat: --numstat | gawk '{ a ...

  2. 《oracle每天一练》触发器不能调用或间接调用COMMIT,ROLLBACK等DCL语句

    触发器不能调用或间接调用COMMIT,ROLLBACK等DCL语句 在触发器中不能运行 ddl语句和commit,rollback语句 ddl语句:DDL语句用语定义和管理数据库中的对象,如Creat ...

  3. centos6.5 tomcat开机启动

    可参考:centos6.5 nginx开机启动 /etc/init.d/下添加tomcatd文件,内容如下: #!/bin/sh # # chkconfig: - # # Licensed to th ...

  4. 【小姿势】如何搭建ipa下载web服务器(直接在手机打开浏览器安装)

    前提: 1) 有个一个现成的web服务器,我用是nodejs. 2) 有个能在用你手机安装的ipa 3) 有个github账号 开搞: 1.用http://plist.iosdev.top/plist ...

  5. iOS 关于iphone6 和 iphone6 plus 的适配

    http://www.ui.cn/detail/26980.html 根据上面说的,iphone6 plus的屏幕的编程时的宽度应该是414,我理解的也是这样,但是我用iphone6 plus 模拟器 ...

  6. PHP javascript cookie

    2015-07-30 16:54:58 ................................cao!!!! 汉字, 邮箱的@符号 容易出错 PHP setcookie 的时候, 不要url ...

  7. vSphere Client无法连接到服务器 出现未知错误的解决方法

    VMware ESXi服务器虚拟机在正常使用过程中,有时候会突然出现远程连接不上的问题,那么这个时候使用vSphere Client连接会出现如下错误: 虽然连接不上,但是可以ping通,所以分析有可 ...

  8. SQL Server遍历表的几种方法 转载

    SQL Server遍历表的几种方法 阅读目录 使用游标 使用表变量 使用临时表 在数据库开发过程中,我们经常会碰到要遍历数据表的情形,一提到遍历表,我们第一印象可能就想到使用游标,使用游标虽然直观易 ...

  9. 【hadoop2.6.0】利用JAVA API 实现数据上传

    原本的目的是想模拟一个流的上传过程,就是一边生成数据,一边存储数据,因为能用上HADOOP通常情况下原本数据的大小就大到本地硬盘存不下.这一般是通过把数据先一部分一部分的缓冲到本地的某个文件夹下,hd ...

  10. 【python】IP地址处理模块IPy

    来源:https://pypi.python.org/pypi/IPy IPy模块 该模块可以方便的处理IPv4和IPv6地址. 以下是从来源中拷贝的一些例子: >>> from I ...