hdu_1875_畅通工程再续 prim和kruskal
这个题是个典型的最小生成树的题目,但是刚开始怎么都过不了,后来发现两种写法都有疏忽,但是prim的到目前为止不懂为什么刚开始的不对,kruskal算法,并查集的初始条件从0开始写成从1开始了,所以已知wa,还有这个题比最小生成树一个卡点就是处理两点之间的距离的时候,要保证点都在10-1000之间。其它的没有什么坑了。
代码一(prim)
#include <stdio.h>
#include <string.h>
#include <math.h>
#define INFI 999999999.0 using namespace std;
const int N = ;
typedef struct point
{
int x, y;
}point;
double Map[N][N];
point p[N];
int vis[N];
double ans;
double low_cost[N];
double calc(int a, int b)
{
return sqrt((p[b].y - p[a].y) * (p[b].y - p[a].y) + (p[b].x - p[a].x) * (p[b].x - p[a].x));
}
void calc_distance(int n)
{
memset(Map, , sizeof(Map));
double t;
for (int i = ; i < n; i++)
{
for (int j = i + ; j < n; j++)
{
t = calc(i, j);
if (t >= && t <= )
Map[i][j] = Map[j][i] =calc(i, j);
else
Map[i][j] = Map[j][i] = INFI;
} }
}
int prim(int n)
{
for (int i = ; i < n; i++)
low_cost[i] = Map[][i];
vis[] = ;
for (int i = ; i < n; i++)
{
int k = ;
double min = INFI;
for (int j = ; j < n; j++)
{
if (!vis[j] && min > low_cost[j])
{
min = low_cost[j];
k = j;
}
}
if (k != )
{
vis[k] = ;
ans += min;
}
else
return ;
for (int j = ; j < n; j++)
{
if (!vis[j] && Map[k][j] < low_cost[j])
low_cost[j] = Map[k][j];
}
}
return ;
}
int main()
{
int T, C;
scanf("%d", &T);
while (T--)
{
memset(vis, , sizeof(vis));
ans = 0.0;
scanf("%d", &C);
for (int i = ; i < C; ++i)
scanf("%d %d", &p[i].x, &p[i].y);
calc_distance(C);
int t = prim(C);
if (t == )
{
puts("oh!");
continue;
}
ans *= 100.0;
printf("%.1f\n", ans);
}
return ;
}
代码二(kruskal)
#include<iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <algorithm>
#define EPS 1e-10
using namespace std;
struct Point{
int x, y;
};
struct edge{
int s, e;
double dis;
};
const int N = ;
int father[N], num[N];
Point p[N];
edge E[N * N / ];
double ans = 0.0;
void init(int n)
{
for (int i = ; i <= n; ++i)
{
father[i] = i;
num[i] = ;
}
}
double calct(int a, int b)
{
return sqrt((p[b].y - p[a].y) * (p[b].y - p[a].y) + (p[b].x - p[a].x) * (p[b].x - p[a].x));
}
int calc_distance(int n)
{
int k = ;
for (int i = ; i < n; i++)
{
for (int j = i + ; j < n; j++)
{
double t = calct(i, j);
if (t >= 10.0 && t <= 1000.0)
{
E[k].s = i;
E[k].e = j;
E[k++].dis = t;
}
}
}
return k;
}
bool cmp(edge a, edge b)
{
return a.dis < b.dis;
}
int find(int x)
{
while (x != father[x])
x = father[x];
return father[x];
}
bool merge(int a, int b)
{
int ta = find(a);
int tb = find(b);
if (ta == tb)
return false;
if (num[ta] > num[tb])
{
father[tb] = ta;
num[ta] += num[tb];
}
else
{
father[ta] = tb;
num[tb] += num[ta];
}
return true;
}
bool kruskal(int n, int len)
{
int k = ;
for (int i = ; i < len; i++)
{
if (merge(E[i].s, E[i].e))
{
++k;
ans += E[i].dis;
}
if (k == n - )
break;
}
if (k == n - )
return true;
return false;
}
int main()
{
int t,n;
scanf("%d", &t);
while (t--)
{
scanf("%d", &n);
init(n);
ans = 0.0;
for (int i = ; i < n; i++)
scanf("%d %d", &p[i].x, &p[i].y);
int len = calc_distance(n);
sort(E, E + len, cmp);
if (kruskal(n, len))
{
printf("%.1f\n", ans * 100.0);
}
else
puts("oh!");
}
return ;
}
hdu_1875_畅通工程再续 prim和kruskal的更多相关文章
- HDU1875——畅通工程再续(最小生成树:Kruskal算法)
畅通工程再续 Description相信大家都听说一个“百岛湖”的地方吧,百岛湖的居民生活在不同的小岛中,当他们想去其他的小岛时都要通过划小船来实现.现在政府决定大力发展百岛湖,发展首先要解决的问题当 ...
- hdu 1875 畅通工程再续(prim方法求得最小生成树)
题目:http://acm.hdu.edu.cn/showproblem.php?pid=1875 /************************************************* ...
- HDU_1875_畅通工程再续
畅通工程再续 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Subm ...
- 还是畅通工程(prim和kruskal)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1233 还是畅通工程 Time Limit: 4000/2000 MS (Java/Others) ...
- HDU 1875 畅通工程再续 (Prim)
题目链接:HDU 1875 Problem Description 相信大家都听说一个"百岛湖"的地方吧,百岛湖的居民生活在不同的小岛中,当他们想去其他的小岛时都要通过划小船来实现 ...
- hdu1875 畅通工程再续 最小生成树并查集解决---kruskal
http://acm.hdu.edu.cn/showproblem.php?pid=1875 New~ 欢迎“热爱编程”的高考少年——报考杭州电子科技大学计算机学院关于2015年杭电ACM暑期集训队的 ...
- HDU 1875 畅通工程再续 (prim最小生成树)
B - 畅通工程再续 Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submit S ...
- HDU 1875 畅通工程再续(kruskal)
畅通工程再续 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Sub ...
- 畅通工程再续(MST)
畅通工程再续 Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submit Statu ...
随机推荐
- 模仿qq音乐播放字母效果
html <div class="cont"> <ul class="cont_ul" id="cont_ul"> ...
- javascript学习(知识点整理)
有了这个代码,就可以在定义 中增加更多的控制了 后面会举例关于extjs定义的更多控制 此种方案可以解决定义时需要一些函数调用的情况 函数作用域和声明提前: 即由于js是解释性语言,在执行前会 ...
- ubuntu10.04版本下android源码的编译
首先是网址:http://software.intel.com/en-us/blogs/2012/03/06/hands-on-notesbuild-android-x86-ics-4-virtual ...
- Java学习----方法的重载
一个类中有多个同名的参数不一样的方法. 作用:可以根据不同的条件调用不同的方法. 注意:java不会因为方法的返回类型或者权限的不同而判断为不同的两个方法. public class Student ...
- 下拉列表框 select 动态赋值
<tr> <td class="label">所属群组:</td> <td> <select name="group ...
- jquery ajax(5)form表单序列化
form表单序列化<script type="text/javascript"> $(function(){ $("#send").click(fu ...
- GFStableList Adapter
STL中,list的优点是插入.删除性能极佳(时间复杂度只需O(1)即可),而且非常重要的在删除节点后,其迭代器不失效,但list查找却不擅长.map由于其实现的数据结构为rb-tree,因此,其插入 ...
- CSS3自定义图标
http://ntesmailfetc.blog.163.com/blog/static/206287061201292631536545/ http://www.zhihu.com/question ...
- hdu 5125 magic balls
题意:求a数组的LIS,但是加了一个条件,为了LIS最大 b[i] a[i]可以交换.最多交换m次: 思路:我们令dp[i][j][l]表示i在最长上升子序列中,已经损失j点能量,第i个人转换了ai和 ...
- COJ 0200 Fibonacci
传送门:http://oj.cnuschool.org.cn/oj/home/problem.htm?problemID=200 试题描述: 地球人都知道Fibonicca数列: 1 1 2 3 5 ...