• [题解] uva 11354 Bond(kruskal最小生成树+倍增LCA)


    - 传送门 -

     https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2339

    # 11354 - Bond Time limit: 8.000 seconds | [Root](https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=0) | [![Submit](https://uva.onlinejudge.org/components/com_onlinejudge/images/button_submit.png "Submit")](https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=submit_problem&problemid=2339&category=) [![Problem Stats](https://uva.onlinejudge.org/components/com_onlinejudge/images/button_stats.png "Problem Stats")](https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=problem_stats&problemid=2339&category=) [![uDebug](https://uva.onlinejudge.org/components/com_onlinejudge/images/button_debug.png)](https://www.udebug.com/UVa/11354) [![Download as PDF](https://uva.onlinejudge.org/components/com_onlinejudge/images/button_pdf.png "Download as PDF")](https://uva.onlinejudge.org/external/113/11354.pdf) | ###(题面见pdf)
      ### - 题意 -  求图中两点间路径最大值(经过的权值最大的一条路)的最小值.   ### - 思路 -  即最小瓶颈路, 因为最小瓶颈路是在最小生成树上的, 我们先求出最小生成树, 然后因为询问和点数太多, 不能暴搜乱搞, 就在树上来一发LCA啦~    细节见代码.   ### - 代码 - ```c++ #include #include #include using namespace std;

    const int N = 5e4 + 5;
    const int M = 1e5 + 5;
    const int inf = 0x7fffffff;

    struct edge {
    int x, y, v;
    }W[M];

    int D[N], ANC[N][18], MA[N][18];
    int HD[N], NXT[M], TO[M], V[M];
    int F[N];
    int n, m, q, cnt, sz, tot;

    bool cmp (edge a, edge b) { return a.v < b.v; }

    void init() {
    sz = cnt = tot = 0;
    memset(ANC, 0, sizeof (ANC));
    memset(MA, 0, sizeof (MA));
    memset(HD, 0, sizeof (HD));
    memset(D, 0, sizeof (D));
    for (int i = 1; i <= n; ++i)
    F[i] = i;
    }

    void add(int x, int y, int v) {
    TO[++tot] = y; NXT[tot] = HD[x]; HD[x] = tot; V[tot] = v;
    TO[++tot] = x; NXT[tot] = HD[y]; HD[y] = tot; V[tot] = v;
    }

    int find(int x) { return x == F[x] ? x : F[x] = find(F[x]); }

    void kruskal() {
    for (int i = 0; i < m; ++i) {
    int fx = find(W[i].x), fy = find(W[i].y);
    if (fx == fy) continue;
    cnt ++;
    F[fx] = fy;
    add(W[i].x, W[i].y, W[i].v);
    if (cnt == n - 1) break;
    }
    }

    void dfs(int x) {
    for (int i = 1; i <= 16; ++i) {
    ANC[x][i] = ANC[ANC[x][i-1]][i-1];
    MA[x][i] = max(MA[x][i-1], MA[ANC[x][i-1]][i-1]);
    }
    for (int i = HD[x]; i; i = NXT[i]) {
    int v = TO[i];
    if (v != ANC[x][0]) {
    D[v] = D[x] + 1;
    ANC[v][0] = x;
    MA[v][0] = V[i];
    dfs(v);
    }
    }
    }

    void lca(int x, int y) {
    int ans = -inf;
    if (D[x] < D[y]) swap(x, y);
    for (int i = 16; i >= 0; --i)
    if (D[ANC[x][i]] >= D[y]) {
    ans = max(ans, MA[x][i]);
    x = ANC[x][i];
    }
    if (x != y) {
    for (int i = 16; i >= 0; --i)
    if (ANC[x][i] != ANC[y][i]) {
    ans = max(ans, MA[x][i]);
    ans = max(ans, MA[y][i]);
    x = ANC[x][i];
    y = ANC[y][i];
    }
    ans = max(ans, MA[x][0]);
    ans = max(ans, MA[y][0]);
    }
    printf("%d ", ans);
    }

    int main() {
    int cas = 0;
    while (scanf("%d%d", &n, &m) != EOF) {
    if (cas) printf(" ");
    else cas ++;
    init();
    for (int i = 0; i < m; ++i)
    scanf("%d%d%d", &W[i].x, &W[i].y, &W[i].v);
    sort(W, W + m, cmp);
    kruskal();
    for (int i = 1; i <= n; ++i)
    if (!D[i]) dfs(i);
    scanf("%d", &q);
    for (int i = 1, x, y; i <= q; ++i) {
    scanf("%d%d", &x, &y);
    lca(x, y);
    }
    }
    return 0;
    }

  • 相关阅读:
    判断大文件是否上传成功(一个大文件上传到ftp,判断是否上传完成)
    hbase的region
    把hdfs数据写入到hbase表
    eclipse和scala整合,打包配置文件及打包步骤
    sparkStreaming 读kafka的数据
    脚本put数据到hdfs
    Hive的自定义函数
    Ftp客户端需要TSL功能的文件上传
    Hive中的数据库、表、数据与HDFS的对应关系
    一文了解RPC框架原理
  • 原文地址:https://www.cnblogs.com/Anding-16/p/7360300.html
Copyright © 2020-2023  润新知