不贴题目了
这个题太有意思了!!!
没想到最小生成树的题还能这么搞
竟然一个是托 最后又到最小生成树的经典做法上了
第一次没对 我又仔细看了看题 原来这个也是最小权重啊 我一开始根本没考虑最小的问题
只是把不在一块的岛 连了起来
后来又改了几次 样例都对 我觉得也没啥毛病 但 啊 就是不对
后来我又从CSDN上搜了
那个作者说的让我突然又思路了:
需要往模板方向靠拢,在要求的条件之下,化为: 村1 村2 距离/价钱
不就是把他们两个两个的遍历一遍吗 然后记下他们的编号 和他们之间的距离
就成了经典的最小生成树的问题了
// 这个题太有意思了!!!
// 没想到最小生成树的题还能这么搞
// 竟然一个是托 最后又到最小生成树的经典做法上了
// 第一次没对 我又仔细看了看题 原来这个也是最小权重啊 我一开始根本没考虑最小的问题
// 只是把不在一块的岛 连了起来
// 后来又改了几次 样例都对 我觉得也没啥毛病 但 啊 就是不对
// 后来我又从CSDN上搜了
// 那个作者说的让我突然又思路了:
// 需要往模板方向靠拢,在要求的条件之下,化为: 村1 村2 距离/价钱
// 不就是把他们两个两个的遍历一遍吗 然后记下他们的编号 和他们之间的距离
// 就成了经典的最小生成树的问题了
#include <iostream>
#include <vector>
#include <cmath>
#include <numeric>
#include <algorithm>
using namespace std;
//node用来输入
struct node
{
int x, y;
};
//用来之后的最小生成树的模板
struct RODE
{
int a, b;
double t;
};
//排序规则
int cmp(RODE e1, RODE e2)
{
return e1.t < e2.t;
}
vector<node> rode;
vector<RODE> lu;
//dp是祖先
vector<int> dp;
int find(int x)
{
return dp[x] == x ? x : dp[x] = find(dp[x]);
}
//求权重
double jl(int x1, int y1, int x2, int y2)
{
return sqrt(pow(abs(x1 - x2), 2) + pow(abs(y1 - y2), 2));
}
int main()
{
int t, n;
cin >> t;
for (int p = 0; p < t; p++)
{
cin >> n;
rode.resize(n + 1);
dp.resize(n + 1);
lu.resize(n + 1);
//唉 ans=0 一开始没发现没赋初值
double ans = 0;
for (int i = 1; i <= n; i++)
{
cin >> rode[i].x >> rode[i].y;
}
//给默认祖先
iota(dp.begin(), dp.end(), 0);
//遍历 rode
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
if (i != j)
{
//求权重再给 lu
double jul = jl(rode[i].x, rode[i].y, rode[j].x, rode[j].y);
lu.push_back({i, j, jul});
}
}
}
sort(lu.begin(), lu.end(), cmp);
for (auto e : lu)
{
if (e.t < 10 || e.t > 1000)
continue;
int x = find(e.a);
int y = find(e.b);
if (x != y)
{
n--;
ans += e.t;
dp[x] = y;
}
}
if (n == 1)
printf("%.1f\n", ans * 100);
else
cout << "oh!\n";
//恢复默认
rode.clear();
lu.clear();
dp.clear();
}
return 0;
}
来源:CSDN
作者:陌陌623
链接:https://blog.csdn.net/weixin_45653525/article/details/104112931