zoukankan      html  css  js  c++  java
  • 寒假训练记录——1月25日

    这段时间应该是要写最短路,生成树,lca和树的直径什么的。

    ZOJ-1586

     最小生成树,但是每条边的权值还要加上该边两端节点的权值。

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<string>
    #include<cstdio>
    #include<vector>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<map>
    
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    const int maxn = 1e6 + 5;
    const int INF = 0x3f3f3f3f;
    const int mod = 1e9 + 7;
    
    int s[10005];
    int price[1005];
    int mp[1005][1005];
    
    struct Edge {
        int u, v, val;
    }edge[maxn];
    
    bool cmp(Edge a, Edge b) {
        return a.val < b.val;
    }
    
    int get(int x) {
        if (x == s[x]) return x;
        return s[x] = get(s[x]);
    }
    
    int kru(int n, int m) {
        int ans = 0, cnt = 0;
        for (int i = 1; i <= n; i++) s[i] = i;
        sort(edge + 1, edge + 1 + m, cmp);
        for (int i = 1; i <= m; i++) {
            int x = get(edge[i].u);
            int y = get(edge[i].v);
            if (x == y) continue;
            s[x] = y;
            ans += edge[i].val;
            cnt++;
            if (cnt == n - 1) break;
        }
        return ans;
    }
    
    int main()
    {
        int t;
        scanf("%d", &t);
        while (t--) {
            memset(mp, 0, sizeof(mp));
            int n;
            scanf("%d", &n);
            for (int i = 1; i <= n; i++) scanf("%d", &price[i]);
            for (int i = 1; i <= n; i++) {
                for (int j = 1; j <= n; j++) {
                    scanf("%d", &mp[i][j]);
                }
            }
            int cnt = 0;
            for (int i = 1; i <= n; i++) {
                for (int j = 1; j <= n; j++) {
                    if (i != j) {
                        edge[++cnt].u = i;
                        edge[cnt].v = j;
                        edge[cnt].val = mp[i][j] + price[i] + price[j];
                    }
                }
            }
            int ans = kru(n, cnt);
            printf("%d
    ", ans);
        }
        return 0;
    }
    View Code

     HDU-2586

    lca,倍增。树上两点的距离 d(x, y) = h(x) + h(y) - 2*h(lca(x, y))

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<string>
    #include<cstdio>
    #include<vector>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<map>
    
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    const int maxn = 1e5 + 5;
    const int INF = 0x3f3f3f3f;
    const int mod = 1e9 + 7;
    
    int tot = 0, t;
    int head[maxn], Next[maxn], edge[maxn], ver[maxn];
    int f[maxn][30], d[maxn], dist[maxn];
    
    void add(int x, int y, int z) {
        ver[++tot] = y;
        edge[tot] = z;
        Next[tot] = head[x];
        head[x] = tot;
    }
    
    void bfs() {
        queue<int>qe;
        qe.push(1); d[1] = 1;
        while (qe.size()) {
            int x = qe.front();
            qe.pop();
            for (int i = head[x]; i; i = Next[i]) {
                int y = ver[i];
                if (d[y]) continue;
                d[y] = d[x] + 1;
                dist[y] = dist[x] + edge[i];
                f[y][0] = x;
                for (int j = 1; j <= t; j++) {
                    f[y][j] = f[f[y][j - 1]][j - 1];
                }
                qe.push(y);
            }
        }
    }
    
    int lca(int x, int y) {
        if (d[x] > d[y]) swap(x, y);
        for (int i = t; i >= 0; i--) {
            if (d[f[y][i]] >= d[x]) y = f[y][i];
        }
        if (x == y) return x;
        for (int i = t; i >= 0; i--) {
            if (f[x][i] != f[y][i]) x = f[x][i], y = f[y][i];
        }
        return f[x][0];
    }
    
    int main()
    {
        int T;
        scanf("%d", &T);
        while (T--) {
            int n, m;
            scanf("%d %d", &n, &m);
            t = (int)(log(n) / log(2)) + 1;
            tot = 0;
            memset(head, 0, sizeof(head));
            memset(d, 0, sizeof(d));
            for (int i = 0; i < n - 1; i++) {
                int u, v, val;
                scanf("%d %d %d", &u, &v, &val);
                add(u, v, val);
                add(v, u, val);
            }
            bfs();
            for (int i = 1; i <= m; i++) {
                int x, y;
                scanf("%d%d", &x, &y);
                printf("%d
    ", dist[x] + dist[y] - 2 * dist[lca(x, y)]);
            }
        }
        return 0;
    }
    View Code

    POJ-1986

    lca

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<string>
    #include<cstdio>
    #include<vector>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<map>
    
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    const int maxn = 1e5 + 5;
    const int INF = 0x3f3f3f3f;
    const int mod = 1e9 + 7;
    
    int tot = 0, t;
    int head[maxn], Next[maxn], edge[maxn], ver[maxn];
    int f[maxn][30], d[maxn], dist[maxn];
    
    void add(int x, int y, int z) {
        ver[++tot] = y;
        edge[tot] = z;
        Next[tot] = head[x];
        head[x] = tot;
    }
    
    void bfs() {
        queue<int>qe;
        qe.push(1); d[1] = 1;
        while (qe.size()) {
            int x = qe.front();
            qe.pop();
            for (int i = head[x]; i; i = Next[i]) {
                int y = ver[i];
                if (d[y]) continue;
                d[y] = d[x] + 1;
                dist[y] = dist[x] + edge[i];
                f[y][0] = x;
                for (int j = 1; j <= t; j++) {
                    f[y][j] = f[f[y][j - 1]][j - 1];
                }
                qe.push(y);
            }
        }
    }
    
    int lca(int x, int y) {
        if (d[x] > d[y]) swap(x, y);
        for (int i = t; i >= 0; i--) {
            if (d[f[y][i]] >= d[x]) y = f[y][i];
        }
        if (x == y) return x;
        for (int i = t; i >= 0; i--) {
            if (f[x][i] != f[y][i]) x = f[x][i], y = f[y][i];
        }
        return f[x][0];
    }
    
    int main()
    {
    
        int n, m;
        scanf("%d %d", &n, &m);
        t = (int)(log(n) / log(2)) + 1;
        tot = 0;
        memset(head, 0, sizeof(head));
        memset(d, 0, sizeof(d));
        for (int i = 1; i <= m; i++) {
            int u, v, val;
            scanf("%d %d %d", &u, &v, &val);
            string s;
            cin >> s;
            add(u, v, val);
            add(v, u, val);
        }
        bfs();
        int q;
        scanf("%d", &q);
        for (int i = 1; i <= q; i++) {
            int x, y;
            scanf("%d%d", &x, &y);
            printf("%d
    ", dist[x] + dist[y] - 2 * dist[lca(x, y)]);
        }
        return 0;
    }
    View Code

    POJ-1330

    lca,这里的root不一定1

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<string>
    #include<cstdio>
    #include<vector>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<map>
    
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    const int maxn = 1e5 + 5;
    const int INF = 0x3f3f3f3f;
    const int mod = 1e9 + 7;
    
    int tot = 0, t;
    int head[maxn], Next[maxn], edge[maxn], ver[maxn];
    int f[maxn][30], d[maxn], dist[maxn];
    
    void add(int x, int y) {
        ver[++tot] = y;
        Next[tot] = head[x];
        head[x] = tot;
    }
    
    void bfs(int root) {
        queue<int>qe;
        qe.push(root); d[root] = 1;
        while (qe.size()) {
            int x = qe.front();
            qe.pop();
            for (int i = head[x]; i; i = Next[i]) {
                int y = ver[i];
                if (d[y]) continue;
                d[y] = d[x] + 1;
                f[y][0] = x;
                for (int j = 1; j <= t; j++) {
                    f[y][j] = f[f[y][j - 1]][j - 1];
                }
                qe.push(y);
            }
        }
    }
    
    int lca(int x, int y) {
        if (d[x] > d[y]) swap(x, y);
        for (int i = t; i >= 0; i--) {
            if (d[f[y][i]] >= d[x]) y = f[y][i];
        }
        if (x == y) return x;
        for (int i = t; i >= 0; i--) {
            if (f[x][i] != f[y][i]) x = f[x][i], y = f[y][i];
        }
        return f[x][0];
    }
    
    int main()
    {
        int T;
        scanf("%d", &T);
        while (T--) {
            int n, m;
            scanf("%d", &n);
            t = (int)(log(n) / log(2)) + 1;
            tot = 0;
            memset(head, 0, sizeof(head));
            memset(d, 0, sizeof(d));
            int root = -1;
            for (int i = 1; i <= n - 1; i++) {
                int u, v;
                scanf("%d %d", &u, &v);
                if (root == -1) root = u;
                add(u, v);
                add(v, u);
            }
            bfs(root);
            int x, y;
            scanf("%d %d", &x, &y);
            printf("%d
    ", lca(x, y));
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Python的第一个程序
    Spring Boot 之Web开发
    JAVA简介及特性
    Spring Boot与Docker
    ls命令之通配符的使用
    [导入]ASP.NET常用函数
    [导入]再见号称中国最美的女人
    [导入]www.reactos.org一网友介绍的方向为“自己写操作系统的站点”
    [导入] Gmail Chat (Gmail 里的聊天功能)
    [导入]此篇写给城里普通收入的年轻人~~~
  • 原文地址:https://www.cnblogs.com/zny0222/p/14324854.html
Copyright © 2011-2022 走看看