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 ...
随机推荐
- Quartz 之 windowService
(一)创建服务 QuarzService using System.ServiceProcess;using System.Text; using Quartz;using Quartz.Impl; ...
- Dataset
1,if(ds == null) 这是判断内存中的数据集是否为空,说明DATASET为空,行和列都不存在!! 2,if(ds.Tables[0].Count == 0) 这应该是在内存中存在一个DAT ...
- Yii 权限分级式访问控制实现(非RBAC法)
以下由我们在信易网络公司开发项目的时候终结出的一些经验 主要参考资料:yii官网http://www.yiiframework.com/wiki/60/yii framework 提供了2套权限访问系 ...
- [About me] 关于Alima博主
大家好,欢迎来到我的博客,我是博主Alima. 关于我,一个从岛国工作刚刚失望回国的90后男孩子,被日企伤的很难过. 迫切的想改变现在的一切,想换个城市换个工作方向,重新开始. 如果你,觉得我的博客写 ...
- Python学习笔记——正则表达式入门
# 本文对正则知识不做详细解释,仅作入门级的正则知识目录. 正则表达式的强大早有耳闻,大一时参加一次选拔考试,题目就是用做个HTML解析器,正则的优势表现得淋漓尽致.题外话不多讲,直接上干货: 1. ...
- wysiwyg editor
http://www.bootcss.com/p/bootstrap-wysiwyg/
- bzoj 3781: 小B的询问 分块
3781: 小B的询问 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 196 Solved: 135[Submit][Status] Descrip ...
- PS字体工具字体显示不出来
显示一个小点:搜索了各种答案,扩大字号(最大72)更改前景色和背景色,最正确的解释就是分辨率太低,我发现分辨率是1,一般的设置成300,1分辨率情况下可以在图层那选择文字图层,然后按ctrl+t,拉大 ...
- js node
http://blogs.msdn.com/b/scott_hanselman/archive/2011/11/29/window-iis-node-js.aspx http://www.16kan. ...
- 【GDOI2014 DAY2】Beyond (扩展KMP)
[题目] [题意] Jodie和Aiden在做游戏.Jodie在一个长度为l字符串环上走路,他每离开一个就会记下格子当前字符.他让Aiden在他走了一圈后叫他停下来.Aiden决定耍一下Jodie,在 ...