题意简单:去掉最小生成树的某一条边并补上一条,求MaxVal

思路:贪心(借鉴Yamidie的思路。。。)

分别求出最小生成树和次最小生成树,再在这两棵树上求最小生成树

 #include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#include<math.h>
using namespace std;
const int maxn = ;
const int maxm = maxn*maxn;
const int inf1 = 0x3f3f3f3f;
const double inf2 = ; struct Point {
double x,y;
}pnt[ maxn ];
struct Edge{
int u,v;
double val;
int id;
}edge[ maxn<< ];
int cnt_edge;
double mat[ maxn ][ maxn ];
double dis[ maxn ];
bool vis[ maxn ];
int pre[ maxn ]; double LenPrim1;
double LenPrim2; int fa[ maxn ],rank[ maxn ]; int find( int x ){
if( x==fa[x] ) return x;
else return fa[ x ] = find( fa[x] );
} void init( int n ){
for( int i=;i<n;i++ ){
fa[ i ] = i;
rank[ i ] = ;
}
return ;
} double dist( int i,int j ){
return sqrt( (pnt[i].x-pnt[j].x)*(pnt[i].x-pnt[j].x)+(pnt[i].y-pnt[j].y)*(pnt[i].y-pnt[j].y) );
} int cmp( Edge a,Edge b ){
return a.val<b.val;
} void GetMap( int n ){
for( int i=;i<n;i++ )
for( int j=;j<n;j++ ){
mat[i][j] = dist( i,j );
//printf("mat[%d][%d]=%.3lf\n",i,j,mat[i][j]);
}
return ;
} double prim( int n,int Belong ){
for( int i=;i<n;i++ ){
dis[ i ] = mat[][i];
vis[ i ] = false;
pre[ i ] = ;
}
vis[] = true;
//if( Belong==2 ){
// for( int i=0;i<n;i++ )for( int j=0;j<n;j++ )
//printf("mat[%d][%d]=%.3lf\n",i,j,mat[i][j]);
//}
double ans = ;
for( int i=;i<n;i++ ){
int id = -;
double M = inf2;
for( int j=;j<n;j++ ){
if( !vis[j] && M>dis[j] ){
M = dis[j];
id = j;
}
}
if( id==- ) break;
vis[ id ] = true;
ans += M;
edge[ cnt_edge ].u = pre[ id ];
edge[ cnt_edge ].v = id;
edge[ cnt_edge ].id = Belong;
edge[ cnt_edge ].val = mat[ id ][ pre[id] ];
//printf("u = %d,v = %d\n",edge[cnt_edge].u,edge[cnt_edge].v);
cnt_edge ++ ;
for( int j=;j<n;j++ ){
if( !vis[j] && dis[j]>mat[id][j] ){
dis[j] = mat[id][j];
pre[ j ] = id;
}
}
}
return ans;
} void Deal( int n ){
for( int i=;i<cnt_edge;i++ ){
mat[ edge[i].u ][ edge[i].v ] = inf2;
mat[ edge[i].v ][ edge[i].u ] = inf2;
}
} double Kruskal( int n,int id ){
double ans = ;
init( n );
int cnt = ;
for( int i=;i<cnt_edge;i++ ){
if( i==id ) continue;
int fx = find( edge[i].u );
int fy = find( edge[i].v );
if( fx!=fy ){
if( rank[ fx ]<rank[ fy ] ){
rank[ fy ] += rank[ fx ];
fa[ fx ] = fy;
}
else {
rank[ fx ] += rank[ fy ];
fa[ fy ] = fx;
}
cnt ++ ;
ans += edge[i].val;
if( cnt==n- ) break;
}
}
return ans;
} int main(){
int T;
scanf("%d",&T);
while( T-- ){
int n;
double k;
scanf("%d%lf",&n,&k);
for( int i=;i<n;i++ )
scanf("%lf%lf",&pnt[i].x,&pnt[i].y);
GetMap( n );
cnt_edge = ;
LenPrim1 = prim( n, );
Deal( n );
LenPrim2 = prim( n, );
double ans = LenPrim1;
double temp_ans = ;
sort( edge,edge+cnt_edge,cmp );
//printf("cnt_edge = %d\n",cnt_edge);
for( int i=;i<cnt_edge;i++ ){
if( edge[i].id== && edge[i].u!= && edge[i].v!= ){
temp_ans = Kruskal( n,i );
if( temp_ans>ans )
ans = temp_ans;
}
}
printf("%.2lf\n",ans*k);
}
return ;
}

HDU4756+Prim的更多相关文章

  1. hdu4126_hdu4756_求最小生成树的最佳替换边_Kruskal and Prim

    目录 Catalog Solution: (有任何问题欢迎留言或私聊 && 欢迎交流讨论哦 Catalog Problem:  Portal: hdu4126 hdu4756  原题目 ...

  2. 图的生成树(森林)(克鲁斯卡尔Kruskal算法和普里姆Prim算法)、以及并查集的使用

    图的连通性问题:无向图的连通分量和生成树,所有顶点均由边连接在一起,但不存在回路的图. 设图 G=(V, E) 是个连通图,当从图任一顶点出发遍历图G 时,将边集 E(G) 分成两个集合 T(G) 和 ...

  3. 最小生成树---Prim算法和Kruskal算法

    Prim算法 1.概览 普里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树.意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点(英语:Vertex (gra ...

  4. 最小生成树(prim&kruskal)

    最近都是图,为了防止几次记不住,先把自己理解的写下来,有问题继续改.先把算法过程记下来: prime算法:                  原始的加权连通图——————D被选作起点,选与之相连的权值 ...

  5. Prim 最小生成树算法

    Prim 算法是一种解决最小生成树问题(Minimum Spanning Tree)的算法.和 Kruskal 算法类似,Prim 算法的设计也是基于贪心算法(Greedy algorithm). P ...

  6. poj1789--最小生成树(prim)

    水题... 题目大意: 用一个7位的字符串代表一个编号,两个编号之间的distance代表这两个编号之间不同字母的个数.一个编号只能由另一个编号“衍生”出来,代价是这两个编号之间相应的distance ...

  7. 最小生成树のprim算法

    Problem A Time Limit : 1000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other) Total Sub ...

  8. poj2485 kruskal与prim

    Kruskal: #include<iostream> #include<cstdio> #include<algorithm> using namespace s ...

  9. 数据结构代码整理(线性表,栈,队列,串,二叉树,图的建立和遍历stl,最小生成树prim算法)。。持续更新中。。。

    //归并排序递归方法实现 #include <iostream> #include <cstdio> using namespace std; #define maxn 100 ...

随机推荐

  1. ASP.NET中页面加载时文本框(texbox控件)内有文字获得焦点时文字消失

    代码如下: <asp:TextBox ID="TextBox1" runat="server" Height="26px" MaxLe ...

  2. JDBC(用Eclipse操作数据库Oracle)的基础操作集合

    JDBC: JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编 ...

  3. Unity3D项目实战笔记(5):延时功能的几种实现

    我所做过的系统,分单机版系统(2005年).CS系统(2010年).实时系统(2015年),各个系统均有“延时”功能:定时调度的: 本博客说的是实时系统中的延时功能(基于Unity3D游戏引擎). 在 ...

  4. iMAC——关闭自动弹出手机照片

    有时当自己的iPhone手机插入一台iMAC电脑时,会自动弹出自己iPhone手机的照片. 这相当影响人的隐私等等,所以顺便将方法(参考网络的)小记一篇博客. 一.OS X 10.10以上用户解决办法 ...

  5. C# @符号的多种使用方法

    1.限定字符串用 @ 符号加在字符串前面表示其中的转义字符“不”被处理.如果我们写一个文件的路径,例如"D:/文本文件"路径下的text.txt文件,不加@符号的话写法如下:str ...

  6. JAVA解析xml的五种方式比较

     1)DOM解析 DOM是html和xml的应用程序接口(API),以层次结构(类似于树型)来组织节点和信息片段,映射XML文档的结构,允许获取 和操作文档的任意部分,是W3C的官方标准 [优点] ① ...

  7. browserify总结

    一.browserify 简介 browserify is a tool for compiling node-flavored commonjs modules for the browser. Y ...

  8. 实现android上解析Json格式数据功能

    实现android上解析Json格式数据功能,该源码转载于安卓教程网的,http://android.662p.com ,个人感觉还不错的,大家可以看看一下吧. package com.practic ...

  9. ajax返回的json内容进行排序

    关键方法:sort()用于对数组的元素进行排序. return a.num-b.num是升序: return b.num-a.num;是降序 writeln在输出后面加\n,在文档里是换行,在html ...

  10. [Testing] 測試理論電子文件

    File path http://files.cnblogs.com/vincentmylee/TestTheory.7z