寒假训练记录——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
原文地址:https://www.cnblogs.com/zny0222/p/14324854.html