HideCharSkinCapInfo

备战传智蓝桥DAY-12

🕒 学习与练习计划

⏰ 时间段📘 内容
12:20-18:40📝 刷Floyd的扩展应用题目 + 做图论工具
20:20-2:30📝 刷Floyd的扩展应用题目 + 做图论工具

完成情况


💡 解题思路与总结

题目1.最短网络 Agri-Net

  • 解题方法:kruskal
  • 解决方案
cpp
#include <bits/stdc++.h>
#define int long long // 仅在需要大整数时使用,memset 数组为 0x3f 时去掉
#define INF 0x3f3f3f3f
#define PII pair<int, int>
#define ULL unsigned long long
#define PIII tuple<int, int, int>
#define all(v) v.begin(), v.end()
#define debug(a) cout << #a << " = " << a << endl;
using namespace std;
constexpr int N = 1 * 1e6 + 10, M = 5 * 1e3 + 10;

int n;
int p[M];
int g[M][M];
int find(int x) {
    if (p[x] != x) p[x] = find(p[x]);
    return p[x];
}
void solve() {
    cin >> n;
    for (int i = 0; i < n; i ++)
        for (int j = 0; j < n; j ++)
            cin >> g[i][j]; 

    vector<pair<int, PII>> nodes;
     for (int i = 0; i < n; i ++)
        for (int j = 0; j < n; j ++) {
            nodes.emplace_back(g[i][j], PII(i, j));
        }

    sort(all(nodes));
    for (int i = 0; i < n; i ++) p[i] = i;

    int res = 0;
    for (auto [w, node] : nodes) {
        auto [a,b] = node;
        a = find(a), b = find(b);
        if (a != b) {
            res += w;
            p[a] = b;
        }
    }

    cout << res << '\n';
}

signed main() {
    ios::sync_with_stdio(0); cin.tie(nullptr), cout.tie(nullptr);
    int _ = 1;
    // cin >> _;
    while (_--) {
        solve();
    }
    return 0;
}

/**
 *    author: Nijika_jia
 *    created: 2025.02.19 12:35:58
 *    description: C++20 Algorithm Template for Competitive Programming
 */

题目2.局域网

  • 解题方法:kruskal
  • 遇到的问题
  • 解决方案
cpp
#include <bits/stdc++.h>
#define int long long // 仅在需要大整数时使用,memset 数组为 0x3f 时去掉
#define INF 0x3f3f3f3f
#define PII pair<int, int>
#define ULL unsigned long long
#define PIII tuple<int, int, int>
#define all(v) v.begin(), v.end()
#define debug(a) cout << #a << " = " << a << endl;
using namespace std;
constexpr int N = 1 * 1e6 + 10, M = 5 * 1e3 + 10;

int n, k;
int p[M];
int find(int x) {
    if (p[x] != x) p[x] = find(p[x]);
    return p[x];
}
void solve() {
    cin >> n >> k;
    vector<pair<int, PII>> nodes;
    while (k --) {
        int i, j, m;
        cin >> i >> j >> m;
        if(!m) continue;
        nodes.emplace_back(m, make_pair(i, j));
    }

    sort(all(nodes));
    for (int i = 1; i <= n; i++) p[i] = i;

    int ans = 0;
    for (auto [w, node] : nodes) {
        auto [a,b] = node;
        a = find(a), b = find(b);
        if (a != b) p[a] = b;
        else ans += w;
    }

    cout << ans << '\n';
}

signed main() {
    ios::sync_with_stdio(0); cin.tie(nullptr), cout.tie(nullptr);
    int _ = 1;
    // cin >> _;
    while (_--) {
        solve();
    }
    return 0;
}

/**
 *    author: Nijika_jia
 *    created: 2025.02.19 12:35:58
 *    description: C++20 Algorithm Template for Competitive Programming
 */

题目3.繁忙的都市

  • 解题方法:Kruskal
  • 遇到的问题
  • 解决方案
cpp
#include <bits/stdc++.h>
#define int long long // 仅在需要大整数时使用,memset 数组为 0x3f 时去掉
#define INF 0x3f3f3f3f
#define PII pair<int, int>
#define ULL unsigned long long
#define PIII tuple<int, int, int>
#define all(v) v.begin(), v.end()
#define debug(a) cout << #a << " = " << a << endl;
using namespace std;
constexpr int N = 1 * 1e6 + 10, M = 300 + 10;

int n, m;
int p[M];
int find(int x) {
    if (p[x] != x) p[x] = find(p[x]);
    return p[x];
}
void solve() {
    cin >> n >> m;
    vector<pair<int, PII>> nodes;
    while (m --) {
        int u, v, c;
        cin >> u >> v >> c;
        nodes.emplace_back(c, make_pair(u, v));
    }

    sort(all(nodes));
    for (int i = 1; i <= n; i ++) p[i] = i;

    int ans;
    for (auto [w, node] : nodes) {
        int a = find(node.first), b = find(node.second);
        if (a != b) {
            p[a] = b;
            ans = w;
        }
    }

    cout << n - 1 << ' ' << ans << '\n';
}

signed main() {
    ios::sync_with_stdio(0); cin.tie(nullptr), cout.tie(nullptr);
    int _ = 1;
    // cin >> _;
    while (_--) {
        solve();
    }
    return 0;
}

/**
 *    author: Nijika_jia
 *    created: 2025.02.19 13:17:56
 *    description: C++20 Algorithm Template for Competitive Programming
 */

题目4.联络员

  • 解题方法:连通块 + Kruskal
  • 解决方案
cpp
#include <bits/stdc++.h>
#define int long long // 仅在需要大整数时使用,memset 数组为 0x3f 时去掉
#define INF 0x3f3f3f3f
#define PII pair<int, int>
#define ULL unsigned long long
#define PIII tuple<int, int, int>
#define all(v) v.begin(), v.end()
#define debug(a) cout << #a << " = " << a << endl;
using namespace std;
constexpr int N = 1 * 1e6 + 10, M = 5 * 1e3 + 10;

int n, m;
int p[M];
int find(int x) {
    if (p[x] != x) p[x] = find(p[x]);
    return p[x];
}
void solve() {
    cin >> n >> m;

    for (int i = 1; i <= n; i ++) p[i] = i; 

    int ans = 0;
    vector<pair<int,PII>> nodes;
    while (m --) {
        int type, u, v, w;
        cin >> type >> u >> v >> w;
        if (type == 1) {
            u = find(u), v = find(v);
            p[u] = v;
            ans += w;
        }else {
            nodes.emplace_back(w, make_pair(u,v));
        }
    }

    sort(all(nodes));

    for (auto [w, node] : nodes) {
        int a = find(node.first), b = find(node.second);
        if (w {
            p[a] = b;
            ans += w;
        }
    }

    cout << ans << '\n';
}

signed main() {
    ios::sync_with_stdio(0); cin.tie(nullptr), cout.tie(nullptr);
    int _ = 1;
    // cin >> _;
    while (_--) {
        solve();
    }
    return 0;
}

/**
 *    author: Nijika_jia
 *    created: 2025.02.19 14:06:21
 *    description: C++20 Algorithm Template for Competitive Programming
 */

题目5.连接格点(grid)

  • 解题方法:先跑横向再跑纵向
  • 解决方案
cpp
#include <bits/stdc++.h>
#define int long long // 仅在需要大整数时使用,memset 数组为 0x3f 时去掉
#define INF 0x3f3f3f3f
#define PII pair<int, int>
#define ULL unsigned long long
#define PIII tuple<int, int, int>
#define all(v) v.begin(), v.end()
#define debug(a) cout << #a << " = " << a << endl;
using namespace std;
constexpr int N = 1 * 1e6 + 10, M = 1 * 1e3 + 10;

int n, m;
int p[M*M], g[M][M];
int find(int x) {
    if (p[x] != x) p[x] = find(p[x]);
    return p[x];
}
void solve() {
    cin >> n >> m;
    
    for (int i = 1,t = 0; i <= n; i ++) 
        for (int j = 1; j <= m; j ++)
            g[i][j] = ++t;

    for (int i = 1; i <= n * m; i ++) p[i] = i;
    
    int x1, y1, x2, y2;
    while(cin >> x1 >> y1 >> x2 >> y2) {
        int a = g[x1][y1], b = g[x2][y2];
        a = find(a), b = find(b);
        p[a] = b;
    }

    int ans = 0;
    for (int i = 1; i < n; i++) {
        for (int j = 1; j <= m; j++) {
            int a = g[i][j], b = g[i + 1][j];
            a = find(a), b = find(b);
            if (a != b) {
                p[a] = b;
                ans ++;
            }
        }
    }

    for (int i = 1; i <= n; i++) {
        for (int j = 1; j < m; j++) {
            int a = g[i][j], b = g[i][j + 1];
            a = find(a), b = find(b);
            if (a != b) {
                p[a] = b;
                ans += 2;
            }
        }
    }

    cout << ans << '\n';
}

signed main() {
    ios::sync_with_stdio(0); cin.tie(nullptr), cout.tie(nullptr);
    int _ = 1;
    // cin >> _;
    while (_--) {
        solve();
    }
    return 0;
}

/**
 *    author: Nijika_jia
 *    created: 2025.02.19 14:30:02
 *    description: C++20 Algorithm Template for Competitive Programming
 */

题目6.新的开始

  • 解题方法:虚拟原点 + Kruskal
  • 解决方案
cpp
#include <bits/stdc++.h>
#define int long long // 仅在需要大整数时使用,memset 数组为 0x3f 时去掉
#define INF 0x3f3f3f3f
#define PII pair<int, int>
#define ULL unsigned long long
#define PIII tuple<int, int, int>
#define all(v) v.begin(), v.end()
#define debug(a) cout << #a << " = " << a << endl;
using namespace std;
constexpr int N = 1 * 1e6 + 10, M = 300 + 10;

int n;
int p[M];
int w[M],g[M][M];
int find(int x) {
    if (p[x] != x) p[x] = find(p[x]);
    return p[x];
}
void solve() {
    cin >> n;
    for (int i = 1; i <= n; i ++) cin >> w[i];
    for (int i = 1; i <= n; i ++)
        for (int j = 1; j <= n; j ++)
            cin >> g[i][j];

    vector<pair<int, PII>> nodes;
    for (int i = 1; i <= n; i ++)
        for (int j = 1; j <= n; j ++) 
            if (g[i][j]) nodes.emplace_back(g[i][j], make_pair(i ,j));
    for (int i = 1; i <= n; i++) nodes.emplace_back(w[i], make_pair(0, i));
    
    sort(all(nodes));
    for (int i = 1; i <= n; i ++) p[i] = i;

    int ans = 0;
    for (auto [w, node] : nodes) {
        int a = find(node.first), b = find(node.second);
        if (a != b) {
            p[a] = b;
            ans += w;
        }
    }
    
    cout << ans << '\n';
}

signed main() {
    ios::sync_with_stdio(0); cin.tie(nullptr), cout.tie(nullptr);
    int _ = 1;
    // cin >> _;
    while (_--) {
        solve();
    }
    return 0;
}

/**
 *    author: Nijika_jia
 *    created: 2025.02.19 22:31:32
 *    description: C++20 Algorithm Template for Competitive Programming
 */

题目7.北极通讯网络

  • 解题方法:DFS求连通块个数 + 二分答案 或 Kruskal
  • 解决方案

DFS求连通块个数 + 二分答案

cpp
#include <bits/stdc++.h>
// #define int long long // 仅在需要大整数时使用,memset 数组为 0x3f 时去掉
#define INF 0x3f3f3f3f
#define PII pair<int, int>
#define ULL unsigned long long
#define PIII tuple<int, int, int>
#define all(v) v.begin(), v.end()
#define debug(a) cout << #a << " = " << a << endl;
using namespace std;
constexpr int N = 1 * 1e6 + 10, M = 5 * 1e2 + 10;

int n, k;
int block[M];
vector<PII> axis;
vector<pair<int,double>> G[M];

void dfs(int id,int u,double d) {
    block[u] = id;
    for (auto [v, w] : G[u]) {
        if (!block[v] && w <= d) dfs(id, v, d);
    }
}
void build() {
    auto get_dist = [](const PII &a, const PII &b) {
        return sqrt(pow(a.first - b.first, 2) + pow(a.second - b.second, 2));
    };
    for (int i = 0; i < n; i ++) 
        for (int j = i + 1; j < n; j ++) 
            G[i].emplace_back(j, get_dist(axis[i], axis[j])), G[j].emplace_back(i, get_dist(axis[i], axis[j]));
}
bool check(double d) {
    memset(block, 0, sizeof block);
    int cnt = 0;
    for (int i = 0; i < n; i ++)
        if (!block[i]) dfs(++cnt ,i, d);

    return cnt <= k;
}
void solve() {
    cin >> n >> k;
    for (int i = 0; i < n; i ++) {
        int x, y;
        cin >> x >> y;
        axis.emplace_back(x, y);
    }

    build();

    double l = 0, r = 1e18;
    while (fabs(l - r) > 1e-6) {
        double mid = (l + r) / 2;
        if (check(mid)) r = mid;
        else l = mid;
    }

    printf("%.2lf\n",l);
}

signed main() {
    ios::sync_with_stdio(0); cin.tie(nullptr), cout.tie(nullptr);
    int _ = 1;
    // cin >> _;
    while (_--) {
        solve();
    }
    return 0;
}

/**
 *    author: Nijika_jia
 *    created: 2025.02.19 22:58:01
 *    description: C++20 Algorithm Template for Competitive Programming
 */

Kruskal

cpp
#include <bits/stdc++.h>
// #define int long long // 仅在需要大整数时使用,memset 数组为 0x3f 时去掉
#define INF 0x3f3f3f3f
#define PII pair<int, int>
#define ULL unsigned long long
#define PIII tuple<int, int, int>
#define all(v) v.begin(), v.end()
#define debug(a) cout << #a << " = " << a << endl;
using namespace std;
constexpr int N = 1 * 1e6 + 10, M = 5 * 1e2 + 10;

int n,k;
int p[M];
int find(int x) {
    if (p[x] != x) p[x] = find(p[x]);
    return p[x];
}
void solve() {
    cin >> n >> k;

    vector<PII> axis;
    for (int i = 0; i < n; i ++) {
        int x, y;
        cin >> x >> y;
        axis.emplace_back(x,y);
    } 

    vector<pair<double,PII>> nodes;
    auto get_dist = [](const PII &a, const PII &b) {
        return sqrt(pow(a.first - b.first, 2) + pow(a.second - b.second, 2));
    };
    for (int i = 0; i < n; i ++) 
        for (int j = i + 1; j < n; j ++) 
            nodes.emplace_back(get_dist(axis[i], axis[j]), make_pair(i, j));
    
    sort(all(nodes));
    for (int i = 0; i < n; i ++) p[i] = i;

    int cnt = n;
    double ans;
    for (auto [w, node] : nodes) {
        if(cnt <= k) break;

        int a = find(node.first), b = find(node.second);
        if (a != b) {
            cnt --;
            p[a] = b;
            ans = w;
        }
    }

    printf("%.2lf",ans);
}

signed main() {
    ios::sync_with_stdio(0); cin.tie(nullptr), cout.tie(nullptr);
    int _ = 1;
    // cin >> _;
    while (_--) {
        solve();
    }
    return 0;
}

/**
 *    author: Nijika_jia
 *    created: 2025.02.20 00:24:21
 *    description: C++20 Algorithm Template for Competitive Programming
 */

额外收获:


🔧 改进计划

  • 针对今日问题:
    • 📖 复习:复习了连通块DFS
    • 📊 刷题:最小生成树的题普遍不难
    • 时间管理:今天稍微早起了那么点

📖 明日计划

  • 💻 最小生成树

📝 附注

  • 终于做完了图论用的工具网站了 - 传送门

🍕封面图

头歌包过教程(对付给看输出的那种实验)
Valaxy v0.28.11 驱动|主题-Yunv0.28.11
本站总访问量
本站访客数 人次
本站已运行0 天0 小时0 分0 秒