题目请戳这里

题目大意:给n个点,现在要使这n个点连通,并且要求代价最小。现在有2个点之间不能直接连通(除了第一个点),求最小代价。

题目分析:跟这题一样样的,唉,又是原题。。先求mst,然后枚举边,对于生成树上的边替换,用树形dp O(N^2)求出每条生成树边的最小替代边。然后替换后的最大值。

详情请见代码:

#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<cctype>
#include<map>
#include<vector>
#include<set>
#include<queue>
#include<string>
using namespace std;
const int N = 1005;
const int M = 3000005;
const int inf = 0x3f3f3f3f;
const double eps = 1e-6;
const double PI = acos(-1.0);
typedef __int64 ll;
double dis[N][N];
double dp[N][N];
bool used[N][N];
bool flag[N];
double lowcost[N];
int pre[N],head[N];
struct node
{
int x,y;
}pt[N];
struct nd
{
int to,next;
}e_mst[M];
int n,m,num;
double B;
void build(int s,int e)
{
e_mst[num].to = e;
e_mst[num].next = head[s];
head[s] = num ++;
}
double getdis(int x1,int y1,int x2,int y2)
{
return sqrt((double)(x1 - x2) * (double)(x1 - x2) + (double)(y1 - y2) * (double)(y1 - y2));
}
void prim()
{
B = 0;
int i,j;
memset(flag,false,sizeof(flag));
for(i = 1;i <= n;i ++)
{
lowcost[i] = dis[1][i];
pre[i] = 1;
}
flag[1] = true;
for(i = 1;i < n;i ++)
{
double Min = 100000000.0;
int v;
for(j = 1;j <= n;j ++)
{
if(flag[j] == false && lowcost[j] < Min)
{
Min = lowcost[j];
v = j;
}
}
B += Min;
used[pre[v]][v] = used[v][pre[v]] = true;
build(v,pre[v]);
build(pre[v],v);
flag[v] = true;
for(j = 1;j <= n;j ++)
{
if(flag[j] == false && lowcost[j] > dis[v][j])
{
lowcost[j] = dis[v][j];
pre[j] = v;
}
}
}
}
double dfs(int cur,int u,int fa)
{
double ret = inf;
for(int i = head[u];~i;i = e_mst[i].next)
{
if(e_mst[i].to == fa)
continue;
double tmp = dfs(cur,e_mst[i].to,u);
ret = min(tmp,ret);
dp[u][e_mst[i].to] = dp[e_mst[i].to][u] = min(tmp,dp[u][e_mst[i].to]);
}
if(cur != fa)
ret = min(ret,dis[cur][u]);
return ret;
}
int main()
{
int t,i,j;
scanf("%d",&t);
while(t --)
{
scanf("%d%d",&n,&m);
for(i = 1;i <= n;i ++)
scanf("%d%d",&pt[i].x,&pt[i].y);
for(i = 1;i <= n;i ++)
for(j = 1;j <= i;j ++)
{
dp[i][j] = dp[j][i] = inf;
if(i == j)
dis[i][j] = 0;
else
dis[i][j] = dis[j][i] = getdis(pt[i].x,pt[i].y,pt[j].x,pt[j].y);
}
memset(used,false,sizeof(used));
memset(head,-1,sizeof(head));
num = 0;
prim();
double ans = B;
for(i = 0;i < n;i ++)
dfs(i,i,-1);
for(i = 2;i <= n;i ++)
{
for(j = 2;j < i;j ++)
{
if(used[i][j] == true)
{
ans = max(ans,B-dis[i][j]+dp[i][j]);
}
}
}
printf("%.2lf\n",ans*m);
}
return 0;
}
//718MS 17100K

hdu4756 Install Air Conditioning(MST + 树形DP)的更多相关文章

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

    题意:n-1个宿舍,1个供电站,n个位置每两个位置都有边相连,其中有一条边不能连,求n个位置连通的最小花费的最大值. 析:因为要连通,还要权值最小,所以就是MST了,然后就是改变一条边,然后去找出改变 ...

  2. Install Air Conditioning HDU - 4756(最小生成树+树形dp)

    Install Air Conditioning HDU - 4756 题意是要让n-1间宿舍和发电站相连 也就是连通嘛 最小生成树板子一套 但是还有个限制条件 就是其中有两个宿舍是不能连着的 要求所 ...

  3. HDU 4756 Install Air Conditioning(次小生成树)

    题目大意:给你n个点然后让你求出去掉一条边之后所形成的最小生成树. 比較基础的次小生成树吧. ..先prime一遍求出最小生成树.在dfs求出次小生成树. Install Air Conditioni ...

  4. hdu4126(MST + 树形dp

    题意:       这个题目和hdu4756差不多,是给你一个图,然后是q次改变边的权值,权值只增不减,最后问你每次改变之后的最小树的平均值是多少. 思路:(prim+树形dp)       先跑一边 ...

  5. hdu 4756 Install Air Conditioning

    非正规做法,一个一个的暴,减一下枝,还得采用sort,qsort居然过不了…… #include <cstdio> #include <cmath> #include < ...

  6. hdu 4756 MST+树形dp ****

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

  7. hdu4126Genghis Khan the ConquerorGenghis Khan the Conqueror(MST+树形DP)

    题目请戳这里 题目大意:给n个点,m条边,每条边权值c,现在要使这n个点连通.现在已知某条边要发生突变,再给q个三元组,每个三元组(a,b,c),(a,b)表示图中可能发生突变的边,该边一定是图中的边 ...

  8. HDU 4126 Genghis Khan the Conqueror MST+树形dp

    题意: 给定n个点m条边的无向图. 以下m行给出边和边权 以下Q个询问. Q行每行给出一条边(一定是m条边中的一条) 表示改动边权. (数据保证改动后的边权比原先的边权大) 问:改动后的最小生成树的权 ...

  9. MST + 树形 dp

    Genghis Khan(成吉思汗)(1162-1227), also known by his birth name Temujin(铁木真) and temple name Taizu(元太祖), ...

随机推荐

  1. LinkButton( 按钮)

    一. 加载方式 //class 加载方式<a href="###" class="easyui-linkbutton">按钮</a> / ...

  2. HTML1.0 - html 环境搭建 开发工具

    1. mac  电脑 2. Hbuilder 开发软件 3. 学习基础 HTML 语法 网站  http://www.w3school.com.cn

  3. css单位rem---移动端至宝

    1.rem是什么? rem(font size of the root element)是指相对于根元素的字体大小的单位.简单的说它就是一个相对单位.看到rem大 家一定会想起em单位em(font  ...

  4. 详细介绍ASP.NET页面重定向方法

    ASP.NET中页面重定向的使用的很频繁,实现方法也有不同,自己也试过几种,现在总结一下. 一.Transfer Execute Redirect重定向方法介绍 1.Server.Transfer方法 ...

  5. 使用idea将本地项目上传至github及clone

    一.上传 1.firl->settings 设置git 2.firl->settings 填写自己的登录名和密码,可以使用test测试是否连接成功 3. 就搞定了.github会自动建立一 ...

  6. 清北学堂 Pa

    PA[题目描述]汉诺塔升级了:现在我们有?个圆盘和?个柱子,每个圆盘大小都不一样,大的圆盘不能放在小的圆盘上面,?个柱子从左到右排成一排.每次你可以将一个柱子上的最上面的圆盘移动到右边或者左边的柱子上 ...

  7. lib,dll区别 及 VS中如何添加lib,dll

    1.加载lib/头文件 分两种方法: (1)适用于当前项目 第一步:项目->属性->C/C++->常规->附加包含目录(浏览.h文件的路径) 添加包含文件 第二步:项目-> ...

  8. Qt小程序仿写----FileRead程序

    该程序实现如下功能:1.打开TXT文件A.txt:2.将文件路径显示到一个文本编辑框里面,文件内容显示到一个文本域里面:3.在文本域里面更改文件内容之后,保存文本域的内容到当前文件路径下. 定义了一F ...

  9. uva 10963 - The Swallowing Ground

    #include <iostream> #include <cstdio> #include <cstdlib> #include <set> usin ...

  10. Linux 软链接和硬链接的理解与学习

    理解前提: 首先要知道 Linux任意一个文件包含2个信息:第一个信息就是文件本身存的内容,第二个信息是文件的控制信息(读写,路径,大小等等),这2个信息是分开存储的,明白这点非常重要 理解总结: L ...