[A through study notes] Minimum Spanning Tree

10065. "3.1 cases through a 2" Arctic communications network

#include <bits/stdc++.h>
using namespace std;

const int N = 500005;
int fa[N], n, k, ind;
double x[N], y[N];
void init() {
    for (int i = 0; i <= n; i++) fa[i] = i;
}
int find(int p) { return (p == fa[p]) ? (p) : (fa[p] = find(fa[p])); }
void merge(int p, int q) {
    p = find(p);
    q = find(q);
    fa[p] = q;
}
double dist(double x1, double y1, double x2, double y2) {
    return sqrt(pow((x2 - x1), 2) + pow((y2 - y1), 2));
}
struct Edge {
    int u, v;
    double w;
    bool operator<(const Edge &b) { return w < b.w; }
} e[N];
double ans = 0;
int cnt = 0;

int main() {
    // ios::sync_with_stdio(false);
    cin >> n >> k;
    for (int i = 1; i <= n; i++) {
        cin >> x[i] >> y[i];
    }
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j < i; j++) {
            Edge tmp;
            tmp.u = i;
            tmp.v = j;
            tmp.w = dist(x[i], y[i], x[j], y[j]);
            e[++ind] = tmp;
        }
    }
    sort(e + 1, e + ind + 1);
    init();
    for (int i = 1; i <= ind; i++)
        if (find(e[i].u) != find(e[i].v)) {
            merge(e[i].u, e[i].v);
            ++cnt;
            if (cnt + k <= n)
                ans = max(ans, e[i].w);
        }
    cout << setiosflags(ios::fixed) << setprecision(2) << ans << endl;
}

10066. "one through 3.1 Exercise 1" new beginning

#include <bits/stdc++.h>
using namespace std;

int n, p[1005][1005], ans, dis[1005];

int main() {
    ios::sync_with_stdio(false);
    cin >> n;
    dis[n + 1] = 1e+9;
    for (int i = 1; i <= n; i++) cin >> dis[i];
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++) cin >> p[i][j];
    for (int i = 1; i <= n; i++) {
        int mx = n + 1;
        for (int j = 1; j <= n; j++)
            if (dis[j] && dis[mx] > dis[j])
                mx = j;
        ans += dis[mx];
        for (int j = 1; j <= n; j++) dis[j] = min(dis[j], p[mx][j]);
    }
    cout << ans << endl;
}

10067. "one through 3.1 Exercise 2" complete graph structure

The use of safety edges Theorem

#include <bits/stdc++.h>
using namespace std;
#define ll long long
ll n, m, fa[100005], siz[100005], ans;
ll find(ll p) { return p == fa[p] ? p : (fa[p] = find(fa[p])); }
void merge(ll p, ll q) {
    p = find(p);
    q = find(q);
    if (p > q)
        swap(p, q);
    siz[p] += siz[q];
    fa[q] = p;
}
struct Edge {
    ll u, v, w;
    bool operator<(const Edge &b) { return w < b.w; }
} e[100005];

int main() {
    cin >> n;
    for (ll i = 1; i < n; i++) {
        ll u, v, w;
        cin >> u >> v >> w;
        Edge t;
        t.u = u;
        t.v = v;
        t.w = w;
        e[i] = t;
    }
    sort(e + 1, e + n);
    for (ll i = 1; i <= n; i++) fa[i] = i, siz[i] = 1;
    for (ll i = 1; i < n; i++) {
        ans += siz[find(e[i].u)] * siz[find(e[i].v)] * (e[i].w + 1);
        merge(e[i].u, e[i].v);
    }
    cout << ans - n + 1 << endl;
}

10068. "one through 3.1 Exercise 3" secret transport of milk

#include <bits/stdc++.h>
using namespace std;
#define N 1000005
#define ll long long
struct Edge {
    ll u, v, w;
    bool operator<(const Edge &b) { return w < b.w; }
} e[N];
ll n, m, ans, fa[N];
ll find(ll p) { return p == fa[p] ? p : (fa[p] = find(fa[p])); }
void merge(ll p, ll q) {
    p = find(p);
    q = find(q);
    fa[p] = q;
}
vector<pair<ll, ll> > g[N];
ll h[505][505], vis[505];
void dfs(ll from, ll p) {
    vis[p] = 1;
    for (ll i = 0; i < g[p].size(); i++) {
        ll q = g[p][i].first;
        if (vis[q])
            continue;
        h[from][q] = max(h[from][p], g[p][i].second);
        dfs(from, q);
    }
}
int main() {
    ios::sync_with_stdio(false);
    cin >> n >> m;
    for (ll i = 1; i <= m; i++) {
        ll u, v, w;
        cin >> u >> v >> w;
        e[i].u = u;
        e[i].v = v;
        e[i].w = w;
    }
    sort(e + 1, e + m + 1);
    for (ll i = 1; i <= n; i++) fa[i] = i;
    for (ll i = 1; i <= m; i++) {
        ll p = find(e[i].u), q = find(e[i].v);
        if (p != q) {
            merge(p, q);
            ans += e[i].w;
            g[e[i].u].push_back(make_pair(e[i].v, e[i].w));
            g[e[i].v].push_back(make_pair(e[i].u, e[i].w));
        }
    }
    for (ll i = 1; i <= n; i++) {
        memset(vis, 0, sizeof vis);
        dfs(i, i);
    }
    ll delta = 1e+9;
    for (ll i = 1; i <= m; i++)
        if (e[i].w - h[e[i].u][e[i].v] > 0) {
            delta = min(delta, e[i].w - h[e[i].u][e[i].v]);
        }
    cout << ans + delta << endl;
}

10069. "one through 3.1 Exercise 4" Tree

Obviously having dichotomy

#include <bits/stdc++.h>
using namespace std;
#define ll long long
ll n, m, k, fa[100005];
double ans;
ll find(ll p) { return p == fa[p] ? p : (fa[p] = find(fa[p])); }
void merge(ll p, ll q) {
    p = find(p);
    q = find(q);
    if (p > q)
        swap(p, q);
    fa[q] = p;
}
struct Edge {
    ll u, v, c;
    double w;
    bool operator<(const Edge &b) { return w < b.w; }
} e[100005];

int mst() {
    ans = 0;
    int cnt = 0;
    sort(e + 1, e + m + 1);
    for (ll i = 1; i <= n; i++) fa[i] = i;
    for (ll i = 1; i <= m; i++) {
        if (find(e[i].u) == find(e[i].v))
            continue;
        ans += e[i].w;
        cnt += e[i].c;
        merge(e[i].u, e[i].v);
    }
    return cnt;
}
int s[100005], t[100005], c[100005], col[100005];
int main() {
    ios::sync_with_stdio(false);
    cin >> n >> m >> k;
    for (int i = 1; i <= m; i++) cin >> s[i] >> t[i] >> c[i] >> col[i], ++s[i], ++t[i];
    double l = -1000, r = 1000;
    int cnt;
    while (r - l > 1e-6) {
        double mid = (l + r) / 2.0;
        for (int i = 1; i <= m; i++)
            e[i].u = s[i], e[i].v = t[i], e[i].c = col[i], e[i].w = c[i] + (double)(col[i]) * mid;
        if (mst() > n - k - 1)
            l = mid;
        else
            r = mid;
    }
    cout << (int)(ans - l * (n - k - 1) + 0.01) << endl;
}

Guess you like

Origin www.cnblogs.com/mollnn/p/11614175.html
Recommended