UVA 6199 不定根最小树形图
首先是最小树形图的介绍。
看这个博客。最小树形图
上面介绍的很详细了,我就讲一下这道题的题意。
首先给出一些二维点坐标,这些坐标之间构成一些有向图,根据题意,假设两个点a(x1 ,y1) ,b(x2 ,y2) .当y1 <= y2时,他们之间可以连一条有向边,即a -> b。
就是每个点只能连y坐标大于他的点,然后就构成了一张有向图。
最后求出最少的距离可以使得所有的点都连起来。
刚开始以为直接求出两两之间的距离,然后用kruskal求一遍MST就可以了。但是仔细想了一下,这里有向边的限制就使得一些连边的情况是不可行的。
这道题的正解是最小树形图,而且是最裸的。
因为这道题他的根是不确定的,那么我们可以用一个超级源点,作为他的根,将他和所有的点都连起来,边是inf。
#include <set>
#include <map>
#include <stack>
#include <cmath>
#include <queue>
#include <cstdio>
#include <string>
#include <vector>
#include <iomanip>
#include <cstring>
#include <iostream>
#include <algorithm>
#define Max 2505
#define FI first
#define SE second
#define ll long long
#define PI acos(-1.0)
#define inf 0x3fffffff
#define LL(x) ( x << 1 )
#define bug puts("here")
#define PII pair<int,int>
#define RR(x) ( x << 1 | 1 )
#define mp(a,b) make_pair(a,b)
#define mem(a,b) memset(a,b,sizeof(a))
#define REP(i,s,t) for( int i = ( s ) ; i <= ( t ) ; ++ i ) using namespace std; inline void RD(int &ret) {
char c;
int flag = 1 ;
do {
c = getchar();
if(c == '-')flag = -1 ;
} while(c < '0' || c > '9') ;
ret = c - '0';
while((c=getchar()) >= '0' && c <= '9')
ret = ret * 10 + ( c - '0' );
ret *= flag ;
} inline void OT(int a) {
if(a >= 10)OT(a / 10) ;
putchar(a % 10 + '0') ;
} inline void RD(double &ret) {
char c ;
int flag = 1 ;
do {
c = getchar() ;
if(c == '-')flag = -1 ;
} while(c < '0' || c > '9') ;
ll n1 = c - '0' ;
while((c = getchar()) >= '0' && c <= '9') {
n1 = n1 * 10 + c - '0' ;
}
ll n2 = 1 ;
while((c = getchar()) >= '0' && c <= '9') {
n1 = n1 * 10 + c - '0' ;
n2 *= 10 ;
}
ret = flag * (double)n1 / (double)(n2) ;
}
/*********************************************/
#define N 1005
struct PP{
double x , y ;
}P[N] ;
double getdis(int i ,int j){
return sqrt((P[i].x - P[j].x) * (P[i].x - P[j].x) + (P[i].y - P[j].y) * (P[i].y - P[j].y)) ;
}
struct kdq{
int s , e ;
double l ;
}ed[N * N] ;
int num ;
void add(int s ,int e ,double l){
ed[num].s = s ;
ed[num].e = e ;
ed[num].l = l ;
num ++ ;
}
void init(){
num = 0 ;
}
int n ;
int S ;
int pre[N] , id[N] , vis[N] ;
double in[N] ;
double Directed_MST(int root ,int NV , int NE){
double ret = 0 ;
while(1){
for (int i = 0 ; i < NV ; i ++ )in[i] = inf ;
//找到每个点的最小入边
for (int i = 0 ; i < NE ; i ++ ){
int s = ed[i].s ;
int e = ed[i].e ;
if(ed[i].l < in[e] && s != e){
pre[e] = s ;
in[e] = ed[i].l ;
}
}
//最小入边
// for (int i = 1 ; i < NV ; i ++ ){
// cout << i << " : " << in[i] << endl;
// }
for (int i = 0 ; i < NV ; i ++ ){//除根节点外所有点都找到一条入边
if(i == root)continue ;
if(in[i] == inf)return -1 ;
}
//找环
int cntnode = 0 ;
mem(vis ,-1) ;
mem(id ,-1) ;
in[root] = 0 ;
for (int i = 0 ; i < NV ; i ++ ){
ret += in[i] ;
int v = i ;
while(vis[v] != i && id[v] == -1 && v != root){
vis[v] = i ;
v = pre[v] ;
}
if(v != root && id[v] == -1){
for (int u = pre[v] ; u != v ; u = pre[u]){
id[u] = cntnode ;
}
id[v] = cntnode ++ ;
}
} if(cntnode == 0)break ;//无环
for (int i = 0 ; i < NV ; i ++ ){
if(id[i] == -1)id[i] = cntnode ++ ;
}
//缩点
for (int i = 0 ; i < NE ; i ++ ){
int s = ed[i].s ;
int e = ed[i].e ;
ed[i].s = id[s] ;
ed[i].e = id[e] ;
if(ed[i].s != ed[i].e){
ed[i].l -= in[e] ;
}
}
NV = cntnode ;
root = id[root] ;
}
return ret ;
}
int main() {
while(cin >> n , n ){
int a , b ;
for (int i = 1 ; i <= n ; i ++ ){
scanf("%lf %lf",&P[i].x ,&P[i].y) ;
}
init() ;
double dis_sum = 0 ;
for (int i = 1 ; i <= n ;i ++ ){
for (int j = 1 ; j <= n ;j ++ ){
if(i == j)continue ;
double dis = getdis(i , j) ;
if(P[i].y <= P[j].y){
add(i , j , dis) ;
// cout << dis << endl;
dis_sum += dis ;
}
}
}
S = 0 ;
for (int i = 1 ; i <= n ; i ++ ){
add(S , i , inf - 1 ) ;
}
printf("%.2f\n",Directed_MST(0 , n + 1 , num ) - inf + 1) ;
}
return 0 ;
}
UVA 6199 不定根最小树形图的更多相关文章
- HDU 2121 Ice_cream’s world II 不定根最小树形图
题目链接: 题目 Ice_cream's world II Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Ja ...
- HDUOJ--2121--Ice_cream’s world II【朱刘算法】不定根最小树形图
链接:http://acm.hdu.edu.cn/showproblem.php? pid=2121 题意:n个顶点,m条边,求从某一点起建立有向图最小生成树而且花费最小.输出最小花费和根节点下标. ...
- HDU 4009 不定根最小树形图
讲一下建图过程,首先建立一个超级源点S,对于这个源点,向每个HOUSE连一条有向边,权值为该HOUSE建立WELL的费用,即高度*X. 然后每个可以连边的WELL之间,费用为曼哈顿距离*Y,然后考虑两 ...
- 【UVA 11865】 Stream My Contest (二分+MDST最小树形图)
[题意] 你需要花费不超过cost元来搭建一个比赛网络.网络中有n台机器,编号0~n-1,其中机器0为服务器,其他机器为客户机.一共有m条可以使用的网线,其中第i条网线的发送端是机器ui,接收端是机器 ...
- HDU 2121——Ice_cream’s world II——————【最小树形图、不定根】
Ice_cream’s world II Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64 ...
- HDU 2121:Ice_cream’s world II(不定根的最小树形图)
题目链接 题意 求有向图的最小生成树,且根不定. 思路 最小树形图即求有向图的最小生成树,用的是朱刘算法. 这里不定根,那么可以建立一个虚根,让虚根和所有点相连,权值为一个很大的数(这里直接设为所有边 ...
- Uva 11183 - Teen Girl Squad (最小树形图)
Problem ITeen Girl Squad Input: Standard Input Output: Standard Output You are part of a group of n ...
- UVA 11865 Stream My Contest(最小树形图)
题意:N台机器,M条有向边,总资金C,现要到搭建一个以0号机(服务器)为跟的网路,已知每条网线可以把数据从u传递到v,其带宽为d,花费为c,且d越大,传输速度越快,问能够搭建的传输速度最快的网络d值是 ...
- UVA 11183 Teen Girl Squad 最小树形图
最小树形图模板题 #include <iostream> #include <algorithm> #include <cstdio> #include <c ...
随机推荐
- 【python】元组的插入
>>> temp=(1,2,3,4,5)>>> temp=temp[:2]+(8,)+temp[2:]>>> temp(1, 2, 8, 3, 4 ...
- ubuntu杂记
安装ssh: sudo apt-get install openssh-server sudo /etc/init.d/ssh start 将主机中vmware8的网络改为自动获取ip,就可以ping ...
- iOS 图片填充 UIImageView
UIViewContentModeScaleAspectFit, //这个图片都会在view里面显示,并且比例不变 这就是说 如果图片和view的比例不一样 就会有留白如下图1 UIView ...
- UML 类图的关系
1. 关联关系 1.1 单向关联 . public class ClassA { private ClassB bVar; } public class ClassB { //... } 1.2 ...
- 21个很棒的jQuery分页插件下载
分页是指将一个大内容划分为各种不同的页面,因此网站的分页是一个很重要的部分,必须让内容有组织性和易于访问.分页有各两种不同的方式,手动跟自动.最受欢迎简单和广泛的方法是jQuery插件.下面我们收集了 ...
- malloc(0)的问题
http://blog.csdn.net/js_xj/article/details/5826042 解答: 首先来解释malloc(0)的问题,这个语法是对的,而且确实也分配了内存,但是内存空间是0 ...
- php获取html checkbox的值。
一个小错误,搞了好久: <label><input class="short" type="checkbox" id="is_onl ...
- STL unordered_set
http://www.cplusplus.com/reference/unordered_set/unordered_set/ template < class Key, // unordere ...
- [置顶] 【Git入门之一】Git是神马?
1.Git是神马? 一个开源的分布式版本控制系统,可以有效的高速的控制管理各种从小到大的项目版本.他的作者就是大名鼎鼎的Linux系统创始人Linus. 2.分布式又是神马? 先看看集中式.简单说来, ...
- SFTP文件上传与下载
SFTP是对ftp进行加密的一种文件协议. 首先是先引入:jsch-0.1.42-sources.jar与jsch-0.1.42.jar包 SFTP文件上传与下载. import java.io.Fi ...