题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=4756

题目意思:

n-1个宿舍,1个供电站,n个位置每两个位置都有边相连,其中有一条边不能连,求n个位置连通的最小花费的最大值。

解题思路:

和这道题hdu-4126差不多,不过这题不能去掉与供电站相连的边。不同的是这题是一个完全图,求MST时,用kruscal算法的时间复杂度为elge很高会超时,用prim算法复杂度为n^2,所以选用prim算法。

PS:

double类型的不能用memset,置最大,wa了一个多小时。

代码:

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<ctime>
#define eps 1e-6
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define ll __int64
#define lson l,m,(rt<<1)
#define rson m+1,r,(rt<<1)|1
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std; #define Maxn 1300 struct Po
{
double x,y;
}pp[Maxn]; double dis[Maxn][Maxn]; //原始距离
bool hav[Maxn][Maxn],vis[Maxn]; //是否为最小生成树上的边
int pre[Maxn],;
double dp[Maxn][Maxn];//dp[i][j]表示<i,j>为最小生成树上的边,且去掉该边后,包括点i的连通块中的点集A到包括点j的连通块点集B的最小距离。
int n,m,cnt;
double sum,ans,dd[Maxn]; struct EE //构建最小生成树
{
int v;
struct EE * next;
}ee[Maxn<<1],*head[Maxn<<1]; void add(int a,int b)
{
++cnt;
ee[cnt].v=b;
ee[cnt].next=head[a];
head[a]=&ee[cnt];
}
void prim()
{
cnt=0,sum=0;
memset(vis,false,sizeof(vis));
dd[0]=0;
pre[0]=0;
vis[0]=true;
for(int i=1;i<n;i++)
{
dd[i]=dis[0][i];
pre[i]=0;
}
for(int i=1;i<n;i++) //n-1条边
{
double mi=INF;
int re; for(int j=0;j<n;j++)
{
if(!vis[j]&&dd[j]<mi)
{
mi=dd[j];
re=j;
}
}
vis[re]=true;
sum+=mi;
add(pre[re],re);
add(re,pre[re]); for(int i=0;i<n;i++)
{
if(!vis[i]&&dis[re][i]<dd[i])
{
dd[i]=dis[re][i];
pre[i]=re; //更新到集合的距离
}
}
} } double dfs(int ro,int fa,int cur,int dep) //表示以cur作为当前子树根中所有子树节点到总根ro的最短距离
{
struct EE * p=head[cur];
double mi=INF; if(dep!=1) //不为树根的儿子
mi=dis[cur][ro];
while(p)
{
int v=p->v;
if(v!=fa)
{
//printf(":%d\n",v);
//system("pause");
double tt=dfs(ro,cur,v,dep+1);
mi=min(mi,tt);
dp[cur][v]=dp[v][cur]=min(dp[v][cur],tt);//更新当前边 }
p=p->next;
}
return mi; }
double Dis(int i,int j)
{
return sqrt(pow(pp[i].x-pp[j].x,2.0)+pow(pp[i].y-pp[j].y,2.0));
}
void dfs2(int cur,int fa)
{
struct EE * p=head[cur]; while(p)
{
int v=p->v;
if(v!=fa)
{
if(fa)
ans=max(ans,sum-dis[cur][v]+dp[cur][v]);
dfs2(v,cur);
}
p=p->next;
}
}
int main()
{
// printf("%d\n",INF);
double co;
int tt;
scanf("%d",&tt);
while(tt--)
{
scanf("%d%lf",&n,&co);
for(int i=0;i<n;i++)
scanf("%lf%lf",&pp[i].x,&pp[i].y); for(int i=0;i<n;i++)
{
dis[i][i]=0;
for(int j=i+1;j<n;j++)
{
dis[i][j]=dis[j][i]=Dis(i,j);
//edge[nn].a=i,edge[nn].b=j,edge[nn].c=dis[i][j];
}
}
//printf("%d %d\n",nn,m);
memset(hav,false,sizeof(hav));
memset(head,NULL,sizeof(head));
prim();
for(int i=0;i<n;i++)
for(int j=i+1;j<n;j++)
dp[i][j]=dp[j][i]=INF;
for(int i=0;i<n;i++) //以每个点最为树根,对每条边更新n次
{
dfs(i,i,i,0);
// for(int i=0;i<n;i++)
// for(int j=i+1;j<n;j++)
// {
// printf("i:%d j:%d %lf\n",i,j,dp[i][j]);
// }
//system("pause");
} ans=sum;
//printf("%lf\n",sum);
// for(int i=1;i<n;i++)
// for(int j=i+1;j<n;j++)
// if(hav[i][j])
// ans=max(ans,sum-dis[i][j]+dp[i][j]);
dfs2(0,0);
printf("%.2f\n",ans*co);
}
return 0;
}

MST(prim)+树形dp-hdu-4756-Install Air Conditioning的更多相关文章

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

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

  2. hdu 4756 Install Air Conditioning

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

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

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

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

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

  5. fwt优化+树形DP HDU 5909

    //fwt优化+树形DP HDU 5909 //见官方题解 // BestCoder Round #88 http://bestcoder.hdu.edu.cn/ #include <bits/ ...

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

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

  7. HDU 4126 Genghis Khan the Conqueror 最小生成树+树形dp

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4126 Genghis Khan the Conqueror Time Limit: 10000/50 ...

  8. HDU - 1054 Strategic Game(二分图最小点覆盖/树形dp)

    d.一颗树,选最少的点覆盖所有边 s. 1.可以转成二分图的最小点覆盖来做.不过转换后要把匹配数除以2,这个待细看. 2.也可以用树形dp c.匈牙利算法(邻接表,用vector实现): /* 用ST ...

  9. hdu4126(MST + 树形dp

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

随机推荐

  1. ibatis配置xml文件中CDATA的用法

    ibatis作为一种半自动化的OR Mapping工具,其灵活性日益体现出来,越来越多的人都倾向于在项目中使用.由于Sql中经常有与xml规范相冲突的字符对xml映射文件的合法性造成影响.许多人都知道 ...

  2. Js中的appenChild,insertBefore--createDocumentFragment

    平时项目中会有一些流程,或者是评论相关的东西,这些一般只会是在页面初次加载一部分,剩余部分搞一个更多的标签,当点击更多的时候,ajax请求把所有数据加载完(当然这里也有分页的实现方法,本篇不作讨论), ...

  3. AndroidManifest.xml中的android:name是否带.的区别

    如果android:name所指示的类在定义的package="org.crazyit.ui"下,加不加点无所谓:但如果android:name指示的类在在package下的子包中 ...

  4. 安装完oracle重新启动后报ORA-12514: TNS: 监听程序当前无法识别连接描述符中请求的服务(重启前正常)

    安装完oracle重新启动后报ORA-12514: TNS: 监听程序当前无法识别连接描述符中请求的服务(重启前正常) 刚安装完后用plSql登录正常. 在dos命令行下 输入  sqlplus 用户 ...

  5. ReactiveCocoa 入门学习 (一)

    引言 现在由于需求的不断发展,MVC这个经典的框架由于Controller的任务越来越多,显得"臃肿"了,网上又推出了新的框架,比如MVVM,ReactiveCocoa, 今天就来 ...

  6. jfinal不能正确加载html网页,总是报错的解决方法

    今天自学jfinal,遇到一个很奇怪的问题,render("/index.html");总是报错. 仔细看错误日志,才发现原来是因为html网页放到了WEB-INF文件夹下面了,所 ...

  7. Javascript 数组自定义排序,并获取排序后的保存原索引的同序数组(堆排序实现)

    比如数组A: [ 0: 5, 1: 2, 2: 4, 3: 3, 4: 1 ] 排序后的结果为:[1, 2, 3, 4, 5],但是有时候会有需求想要保留排序前的位置到一个同位数组里,如前例则为:[4 ...

  8. Glibc和GCC,ARM-LINUX-GCC的关系

    看到有些贴子/blog上提到「Glibc编译器」,这是个错误的用语.Glibc不是编译器,Glibc不是编译器,Glibc不是编译器.重要的事情说三遍.GCC才是编译器.

  9. C++类继承内存布局(三)

    参考:http://blog.csdn.net/jiangyi711/article/details/4890889# (三)成员函数 类X中每一个非静态成员函数都会接受一个特殊的隐藏参数——this ...

  10. 【实习记】2014-09-26恢复linux下误删的ntfs盘中的文件

        情景,ubuntu下把NTFS格式的盘中的“实习记”文件夹彻底删除了,追毁莫及,粗心觉不是一件好的事情. linux下回复ntfs盘下的文件不能用ext3grep,而使用debugfs命令实在 ...