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

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

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

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

 #include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
using namespace std;
#define MOD 1000000007
const int INF=0x3f3f3f3f;
const double eps=1e-;
typedef long long ll;
#define cl(a) memset(a,0,sizeof(a))
#define ts printf("*****\n");
const int MAXN=;
int n,m,tt;
/*
* Kruskal算法求MST
*/
const int MAXM=;//最大边数
int tol;//边数,加边前赋值为0
struct Edge
{
int to,next;
}edge[MAXM];
int head[MAXN],tot;
void init()
{
tot = ;
memset(head,-,sizeof(head));
}
void addedge(int u,int v)
{
edge[tot].to = v; edge[tot].next = head[u];
head[u] = tot++;
}
bool mp[MAXN][MAXN];
double dp[MAXN][MAXN];
/*
* Prim求MST
* 耗费矩阵cost[][],标号从0开始,0~n-1
* 返回最小生成树的权值,返回-1表示原图不连通
*/
int vis[MAXN];
double lowc[MAXN];
double Prim(double cost[][MAXN],int n)//点是0~n-1
{
double ans=;
memset(vis,false,sizeof(vis));
vis[]=-;
int last[MAXN];
last[]=;
for(int i=;i<n;i++)lowc[i]=cost[][i];
for(int i=;i<n;i++)
{
double minc=INF;
int p=-;
for(int j=;j<n;j++)
if(vis[j]!=-&&minc>lowc[j])
{
minc=lowc[j];
p=j;
}
if(minc==INF)return -;//原图不连通
mp[vis[p]][p]=mp[p][vis[p]]=;
addedge(vis[p],p);
addedge(p,vis[p]);
ans+=minc;
vis[p]=-;
for(int j=;j<n;j++)
if(vis[j]!=-&&lowc[j]>cost[p][j])
{
vis[j]=p;
lowc[j]=cost[p][j];
}
}
return ans;
}
int x[MAXN],y[MAXN];
double dist[MAXN][MAXN];
double dis(int i,int j)
{
return sqrt((double)(x[i]-x[j])*(double)(x[i]-x[j])+(double)(y[i]-y[j])*(double)(y[i]-y[j]));
}
double dfs(int cur,int u,int fa){
double res=(double)INF;
for(int i=head[u];i!=-;i=edge[i].next){
int v=edge[i].to;
if(v==fa)continue;
double tmp=dfs(cur,v,u);
dp[u][v]=dp[v][u]=min(tmp,dp[u][v]);
res=min(res,tmp);
}
if(fa!=cur){
res=min(res,dist[cur][u]);
}
return res;
}
int main()
{
int i,j,k,ca=;
#ifndef ONLINE_JUDGE
freopen("1.in","r",stdin);
#endif
scanf("%d",&tt);
int val;
while(tt--)
{
init();
tol=;
scanf("%d%d",&n,&val);
cl(dist);
for(i=;i<n;i++)
{
scanf("%d%d",x+i,y+i);
}
for(i=;i<n;i++)
{
for(j=;j<n;j++)
{
dist[i][j]=dist[j][i]=dis(i,j);
}
}
cl(mp);
double sumw=Prim(dist,n);
double Max=sumw;
for(int i=;i<n;i++)
for(int j=i;j<n;j++)
dp[i][j]=dp[j][i]=(double)INF;
for(i=;i<n;i++)
{
dfs(i,i,-);
}
for(i=;i<n;i++) //枚举每条边
{
for(j=i+;j<n;j++)
{
if(mp[i][j]) Max=max(Max,sumw-dist[i][j]+dp[i][j]);
}
}
printf("%.2lf\n",Max*val);
}
}

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. 详解 Too many open files

    运行在Linux系统上的Java程序可能会出现"Too many open files"的异常情况,且常见于高并发访问文件系统,多线程网络连接等场景. 程序经常访问的文件.sock ...

  2. 【leetcode】Next Permutation

    Next Permutation Implement next permutation, which rearranges numbers into the lexicographically nex ...

  3. POJ 2421(prim)

    http://poj.org/problem?id=2421 这个题和poj1258是一样的,只要在1258的基础上那么几行代码,就可以A,水. 题意:还是n连通问题,和1258不同的就是这个还有几条 ...

  4. flume与kafka整合

    flume与kafka整合 前提: flume安装和测试通过,可参考:http://www.cnblogs.com/rwxwsblog/p/5800300.html kafka安装和测试通过,可参考: ...

  5. DELPHI XE5开发WEB服务器及安卓手机客户端

    Xe5开发web服务端和手机客户端 ------------------------------------- Delphi xe5作为最新开发利器,就类似如当年的DELPHI,功能强大,快发速度快, ...

  6. effective OC2.0 52阅读笔记(一 熟悉Objective-C)

    第一章:熟悉Objective-C 1 了解objective-c语言的起源 总结:OC为C语言添加了面向对象的特性,是其超集.采用动态绑定的消息结构而非函数调用,也就是说,要在运行时才检查对象类型及 ...

  7. zookeeper集群搭建(windows环境下)

    本次zk测试部署版本为3.4.6版本,下载地址http://mirrors.cnnic.cn/apache/zookeeper/ 限于服务器个数有限本次测试了两种情况 1.单节点方式:部署在一台服务器 ...

  8. 20145213《Java程序设计》第七周学习总结

    20145213<Java程序设计>第七周学习总结 教材学习内容总结 周末快乐的时间总是短暂的,还没好好感受就到了要写博客的周日.有人喟叹时间都去哪儿了,那本周我们就来认识一下Java里的 ...

  9. mac os 下打开FTP服务器

    mac下一般用smb服务来进行远程文件访问,但要用FTP的话,高版本的mac os默认关掉了,可以用如下命令打开: sudo -s launchctl load -w /System/Library/ ...

  10. endnote设置文献第二行悬挂缩进办法

    参考:http://blog.sina.com.cn/s/blog_62b13cf201014lfr.html  使用[endnote]插入文献后,如果文献稍长些,有第二行,第二行会顶格开始.并且这个 ...