[2020.12.5周六]Boruvka

洛谷P3366

题意:最小生成树模板题

题解:Boruvka算法;

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+50,maxm=2e5+5;
const int MaxN = 5000 + 5, MaxM = 200000 + 5;

int N, M;
int U[MaxM], V[MaxM], W[MaxM],Best[maxn];
bool used[MaxM];
namespace DSU
{
    const int maxn=1e7;
    int  father[maxn],rank[maxn];
    void init(int n){for(int i=1;i<=n;i++) {father[i]=i;rank[i]=1;}}
    int find(int x){return x==father[x]?x:father[x]=find(father[x]);}
    void unionSet(int x,int y)
    {
        int xx=find(x),yy=find(y);
        if(xx==yy) return;
        if(rank[xx]>rank[yy]) swap(xx,yy);
        father[xx]=yy;rank[yy]+=rank[xx];
    }
}
using namespace DSU;
inline bool Better(int x, int y) {
    if (y == 0) return true;
    if (W[x] != W[y]) return W[x] < W[y];
    return x < y;
}

void Boruvka() {
    init(N);
    int merged = 0, sum = 0;
    bool update = true;
    while (update) {
        update = false;
        memset(Best, 0, sizeof Best);

        for (int i = 1; i <= M; ++i) {
            if (used[i] == true) continue;
            int p = find(U[i]), q = find(V[i]);
            if (p == q) continue;
            if (Better(i, Best[p]) == true) Best[p] = i;
            if (Better(i, Best[q]) == true) Best[q] = i;
        }

        for (int i = 1; i <= N; ++i)
            if (Best[i] != 0 && used[Best[i]] == false) {
                update = true;
                merged++; sum += W[Best[i]];
                used[Best[i]] = true;
                unionSet(U[Best[i]],V[Best[i]]);
            }
    }

    if (merged == N - 1) printf("%d
", sum);
    else puts("orz");
}

int main() {
    scanf("%d %d", &N, &M);
    for (int i = 1; i <= M; ++i)scanf("%d%d%d", &U[i], &V[i], &W[i]);
    Boruvka();
    system("pause");
    return 0;
}

洛谷P2504

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+50;
int N, M;
int U[maxn], V[maxn], W[maxn],Best[maxn];
bool used[maxn];int imax=0;
namespace DSU
{
    //const int maxn=1e7;
    int  father[maxn],rank[maxn];
    void init(int n){for(int i=1;i<=n;i++) {father[i]=i;rank[i]=1;}}
    int find(int x){return x==father[x]?x:father[x]=find(father[x]);}
    void unionSet(int x,int y)
    {
        int xx=find(x),yy=find(y);
        if(xx==yy) return;
        if(rank[xx]>rank[yy]) swap(xx,yy);
        father[xx]=yy;rank[yy]+=rank[xx];
    }
}
using namespace DSU;
inline bool Better(int x, int y) {
    if (y == 0) return true;
    if (W[x] != W[y]) return W[x] < W[y];
    return x < y;
}
void Boruvka() {
    init(N);
    int merged = 0, sum = 0;
    bool update = true;
    while (update) {
        update = false;
        memset(Best, 0, sizeof Best);

        for (int i = 1; i <= M; ++i) {
            if (used[i] == true) continue;
            int p = find(U[i]), q = find(V[i]);
            if (p == q) continue;
            if (Better(i, Best[p]) == true) Best[p] = i;
            if (Better(i, Best[q]) == true) Best[q] = i;
        }

        for (int i = 1; i <= N; ++i)
            if (Best[i] != 0 && used[Best[i]] == false) {
                update = true;
                merged++; sum += W[Best[i]];
                used[Best[i]] = true;imax=max(imax,W[Best[i]]);
                unionSet(U[Best[i]],V[Best[i]]);
            }
    }
}
int monkey[505];
pair<int,int>tree[1005];
int main() {
    int Monkeynum;scanf("%d", &Monkeynum);
    for(int i=1;i<=Monkeynum;++i) scanf("%d",&monkey[i]);
    scanf("%d",&N);
    for(int i=1;i<=N;i++)scanf("%d%d",&tree[i].first,&tree[i].second);
    for(int i=1;i<N;i++)
        for(int j=i+1;j<=N;j++)
            ++M,U[M]=i,V[M]=j,W[M]=(tree[i].first-tree[j].first)*(tree[i].first-tree[j].first)+(tree[i].second-tree[j].second)*(tree[i].second-tree[j].second);
    Boruvka();
    int ans=0;
    for(int i=1;i<=Monkeynum;++i) if(monkey[i]*monkey[i]>=imax)ans++;
     printf("%d",ans);
    //system("pause");
    return 0;
}

待补:

Atcoder keyence2019 E

51nod 1496

线性基

XOR-MST

合作 AC自动机

原文地址:https://www.cnblogs.com/zx0710/p/14106089.html