畅通工程再续

心不动则不痛 提交于 2020-01-31 04:34:57

不贴题目了

这个题太有意思了!!!
没想到最小生成树的题还能这么搞
竟然一个是托 最后又到最小生成树的经典做法上了
第一次没对 我又仔细看了看题 原来这个也是最小权重啊 我一开始根本没考虑最小的问题
只是把不在一块的岛 连了起来
后来又改了几次 样例都对 我觉得也没啥毛病 但 啊 就是不对
后来我又从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;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!