hdu 4463 Outlets

点击打开链接hdu 4463

思路:最小生成树+kruskal

分析:
1 题目要求的找到n个商店组成n-1条边,并且要求耐克和苹果商店肯定要相连,求最短长度
2 很明显的最小生成树的模板题,由于要求耐克和苹果的商店要在一起那么就要把这两个商店编号合并到同一个集合,然后在利用kruskal计算。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;

#define MAXN 10010
#define N 55

double ans;
int n , P , Q , pos;
int father[MAXN];
int rank[MAXN];
struct Point{
   int x;
   int y;
}p[N];
struct Edge{
   int x;
   int y;
   double value;
}e[MAXN];

bool cmp(Edge e1 , Edge e2){
   return e1.value < e2.value;
}

void init(){
   pos = 0;
   for(int i = 1 ; i <= n ; i++){
      for(int j = i+1 ; j <= n ; j++){
         double tmpx = (p[i].x-p[j].x)*(p[i].x-p[j].x);
         double tmpy = (p[i].y-p[j].y)*(p[i].y-p[j].y);
         double tmp = sqrt(tmpx+tmpy);
         e[pos].x = i , e[pos].y = j;
         e[pos++].value = tmp;
         if(i == P && j == Q)
            ans = tmp;
      }
   }
}

void init_Set(){
   for(int i = 0 ; i <= n ; i++){
      father[i]= i;
      rank[i] = 0;
   }
}

int find_Set(int x){
   if(father[x] != x)
     father[x] = find_Set(father[x]);
   return father[x];
}

void union_Set(int x  , int y){
   if(rank[x] > rank[y])
     father[y] = x;
   else{
     if(rank[x] == rank[y])
       rank[y]++;
     father[x] = y;
   }
}

void kruskal(){

   init();
   init_Set();
   sort(e , e+pos , cmp);
   union_Set(P , Q);

   for(int i = 0 ; i < pos ; i++){
      int root_x = find_Set(e[i].x);
      int root_y = find_Set(e[i].y);
      if(root_x != root_y){
         ans += e[i].value;
         union_Set(root_x , root_y);
      }
   }
}

int main(){
   while(scanf("%d" , &n) && n){
      scanf("%d%d" , &P , &Q);
      if(P > Q)
         swap(P , Q);
      for(int i = 1 ; i <= n ; i++)
         scanf("%d%d" , &p[i].x , &p[i].y);
      kruskal();
      printf("%0.2lf\n" , ans);
   }
   return 0;
}
时间: 2024-08-03 15:44:39

hdu 4463 Outlets的相关文章

【HDU 4463 Outlets】最小生成树(prim,kruscal都可)

以(x,y)坐标的形式给出n个点,修建若干条路使得所有点连通(其中有两个给出的特殊点必须相邻),求所有路的总长度的最小值. 因对所修的路的形状没有限制,所以可看成带权无向完全图,边权值为两点间距离.因是稠密图,故用邻接矩阵存储更好(完全图,边数e达到n(n-1)/2). 至此,可将问题抽象为求最小生成树的边权和. 用了prim+邻接矩阵,prim+邻接表+堆,kruscal各写了一遍,只是内存稍有差别 对于所给的特殊的两个相邻点,只需在开始循环前把这两个点加入子树集合并更新它们所到达的点的min

最小生成树【完结】

第一题 hdu 1232 畅通工程 点击打开hdu 1232 思路:模板题 点击查看代码 第二题 hdu 1233 还是畅通工程 点击打开hdu 1233 思路:模板题 点击查看代码 第三题 uva 10034 Freckles 点击打开uva 10034 思路:模板题 点击查看代码 第四题 uva 10397 Connect the Campus 点击打开uva 10397 思路:模板题 点击查看代码 第五题 uva 10369 Arctic Network 点击打开uva 10369 思路:

HDOJ(HDU) 2304 Electrical Outlets(求和、、)

Problem Description Roy has just moved into a new apartment. Well, actually the apartment itself is not very new, even dating back to the days before people had electricity in their houses. Because of this, Roy's apartment has only one single wall ou

hdu 1527

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1527 hint:威佐夫博弈 基本类似于模板 #include <iostream> #include <cmath> #include <cstdio> using namespace std; const double q = (1 + sqrt(5.0)) / 2.0; // 黄金分割数 int Wythoff(int a, int b) { if (a > b)

hdu 2551 竹青遍野

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2551 hint:就是读懂题就行了 #include <iostream> #include <cstdio> using namespace std; typedef long long LL; LL data[1005]; int main() { data[0]=0; for(int i=1; i<1005; i++) data[i]+=data[i-1]+i*i*i; LL

hdu 2054 A == B?

http://acm.hdu.edu.cn/showproblem.php?pid=2054 此题巨坑,刚开始我以为是简单的水题,就用strcmp过, but错了,后来经过我苦思冥想,结果还有几组数据 0.0 和 0,1.000和1.0 , 但是我不太确定前面的0是不是有作用我还是写了,但是有人过的时候,前面的0没考虑比如: 002和2可能是相等的,也可能是不想等的所以不用判断,只能说明hdu数据不是很强啊,嘿嘿 代码如下: #include <iostream> #include <c

hdu 4430 Yukari&#039;s Birthday

点击打开链接hdu 4430 思路:枚举r+二分k 分析: 1 题目要求的是找到一组最小的r*k,如果r*k相同那么就找r最小的. 2 很明显k>=2,根据n <= 10^12,那么可以知道r的最大值r<50,所以只要枚举枚举r的值,然后二分k的大小找到所有的解,存入一个结构体里面,然后在对结构体排序,那么这样就可以得到最后的ans 3 注意题目说了中心点最多一个蜡烛,所以写二分的时候应该注意判断的条件: 4 还有可能计算得到结果超了long long直接变成负数所以应该对或则个进行判断

hdu 1238 Substrings

点击打开链接hdu 1238 思路:kmp+暴力枚举子串 分析: 1 题目要求找到一个子串x,满足x或x的逆串是输入的n个字符串的子串,求最大的x,输出x的长度 2 题目的n最大100,每一个字符串的最大长度为100,那么暴力枚举子串就是o(n^2)才10000肯定是不会超时的,但是由于这里涉及到了逆串的问题,所以我们应该还要求出n个子串的逆串,然后在求最大的x. 代码: #include<iostream> #include<algorithm> #include<cstd

hdu 1857 Word Puzzle

点击打开链接hdu 1857 思路:字典树 分析: 1 题目要求的是给定的单词第一个字母在这个矩形里面的最小的坐标 2 矩形的最大500*500,单词的来源有三个方向,并且单词的起点和终点在矩形之内都是可能的.所以的如果利用枚举矩形之内的单词,那么肯定是超内存的 3 所以我们必须考虑另一种的方法就是对单词进行建字典树,那么我们只要去枚举单词的可能的起点,然后进行查找相应的单词是不是在树上,如果是的话就标记一下当前的坐标. 4 注意由于单词的来源有三个方向,但是因为要求的如果下相同的情况下要求坐标