题意:给你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. python查找并删除相同文件-UNIQ File-wxPython版本

    今天用wxPython做了一个GUI程序,我称之为UNIQ File,实现查找指定目录内的相同文件,主要原理是计算文件的md5值(计算前先找出文件大小相同的文件,然后计算这些文件的md5值,而不是所有 ...

  2. Linq查询非泛型集合要指定Student类型(比如List)

    #region Linq to 集合查询非泛型集合要指定Student类型            //ArrayList list = new ArrayList();            //li ...

  3. 最近开始做Android了

    最近开始做Android,在学习的过程中发现找以前知识很不方便啊,于是决定以后还是把知识记录在博客里吧,说不定也能为他人提供参考!

  4. Redis Sentinel高可用架构

    Redis目前高可用的架构非常多,比如keepalived+redis,redis cluster,twemproxy,codis,这些架构各有优劣,今天暂且不说这些架构,今天主要说说redis se ...

  5. 如果你修改了ashx.cs的命名空间

    如果你修改了ashx.cs的命名空间,记得要同时修改ashx的WebHandler的Class. 在解决方案资源管理器中右键,查看标记

  6. Java for LeetCode 218 The Skyline Problem【HARD】

    A city's skyline is the outer contour of the silhouette formed by all the buildings in that city whe ...

  7. hdu 1002.A + B Problem II 解题报告

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1002 题目意思:就是大整数加法. 两年几前做的,纯粹是整理下来的. #include <stdi ...

  8. AIX系统的环境变量设置

    AIX系统的环境变量设置 用户环境的定义是通过设置环境变量来实现的.AIX系统主要使用两大类profile文件来定义用户环境.一类是用来为所有用户定制环境,另一类是为个人定义自己的环境. 登录时,sh ...

  9. 【linux】vim的一些快捷键

    ctrl+y  :重复上一行内容 v+移动光标  :选择内容 y  :复制选中的内容 p  :在光标处粘贴复制的内容 ctrl+v :进入列模式,可以选择多列数据 dd :剪切一行,也可做删除一行使用

  10. 【Git】自定义Git

    来源:廖雪峰 让Git显示颜色 git config --global color.ui true 忽略特殊文件 有些文件有敏感信息,或者是自动生成的中间文件.不能或不必提交到git,可以用.giti ...