hdu 4756 MST+树形dp ****
题意:给你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 ****的更多相关文章
- hdu4756 Install Air Conditioning(MST + 树形DP)
题目请戳这里 题目大意:给n个点,现在要使这n个点连通,并且要求代价最小.现在有2个点之间不能直接连通(除了第一个点),求最小代价. 题目分析:跟这题一样样的,唉,又是原题..先求mst,然后枚举边, ...
- HDU 2196.Computer 树形dp 树的直径
Computer Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Su ...
- HDU 2196 Computer 树形DP经典题
链接:http://acm.hdu.edu.cn/showproblem.php? pid=2196 题意:每一个电脑都用线连接到了还有一台电脑,连接用的线有一定的长度,最后把全部电脑连成了一棵树,问 ...
- hdu 6201 【树形dp||SPFA最长路】
http://acm.hdu.edu.cn/showproblem.php?pid=6201 n个城市都在卖一种书,该书的价格在i城市为cost[i],商人打算从某个城市出发到另一个城市结束,途中可以 ...
- HDU 2196 Computer 树形DP 经典题
给出一棵树,边有权值,求出离每一个节点最远的点的距离 树形DP,经典题 本来这道题是无根树,可以随意选择root, 但是根据输入数据的方式,选择root=1明显可以方便很多. 我们先把边权转化为点权, ...
- hdu 4081 最小生成树+树形dp
思路:直接先求一下最小生成树,然后用树形dp来求最优值.也就是两遍dfs. #include<iostream> #include<algorithm> #include< ...
- HDU 3899 简单树形DP
题意:一棵树,给出每个点的权值和每条边的长度, 点j到点i的代价为点j的权值乘以连接i和j的边的长度.求点x使得所有点到点x的代价最小,输出 虽然还是不太懂树形DP是什么意思,先把代码贴出来把. 这道 ...
- HDU 4714 Tree2cycle (树形DP)
题意:给定一棵树,断开一条边或者接上一条边都要花费 1,问你花费最少把这棵树就成一个环. 析:树形DP,想一想,要想把一棵树变成一个环,那么就要把一些枝枝叶叶都换掉,对于一个分叉是大于等于2的我们一定 ...
- hdu Anniversary party 树形DP,点带有值。求MAX
Anniversary party Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others ...
随机推荐
- [大坑]FFT学习
[大坑]FFT学习 Macros #define fon(i,s) for(int i=0;i<s; ++i) #define fone(i,s) for(int i=0;i<=s;++i ...
- 在OpenResty中使用lua-zlib的方法
================================================================== 1.查看 zlib在centos 中是否存在? rpm -qa | ...
- (转)Do not use "using" for WCF Clients - 不要将WCF Client 放在 ‘Using’ 代码块中
RT,最近在编写WCF的应用程序,发现WCF client在关闭的时候有可能会抛出异常,经过搜索之后,发些小伙伴们也遇到过类似的问题,遂记载下来,以备自身和其他小伙伴查看. 原文链接:http://w ...
- centos6.5 iptables结合ipset批量屏蔽ip
安装ipset yum install ipset #创建ip地址集合 ipset create bansms hash:net 查找访问了“getVerificationCode”并且次数大于10次 ...
- 转一篇Xcode中利用target编译不同版本的文章
http://www.cocoachina.com/ios/20160331/15832.html 主要说的是,不用自己定义debug宏,而是在xcode的编译配置文件中,设定debug宏,这样,不用 ...
- Semaphore(信号量)
Semaphore msdn介绍: 限制可同时访问某一资源或资源池的线程数. 命名空间: System.Threading 程序集: System(在 System.dll 中) 通俗理解: 1:宾馆 ...
- java web 学习 --第十一天(Java三级考试)
第十天的学习内容:http://www.cnblogs.com/tobecrazy/p/3473954.html Servlet理论知识: 1.servlet 生成class位置 tomcat编译后生 ...
- 9.SpringMVC和json结合传递数据 && 10.SpringMVC获取controller中json的数据
- 【转】Java-----jar反编译修改重新打包
原文链接:http://blog.csdn.net/hekewangzi/article/details/44676797 一.使用反编译工具JD-GUI(JD-GUI相关操作见Java-----反编 ...
- 将项目导入eclipse中出现的jsp页面报错解决