并查集 2016.7.5

1、团体程序设计天梯赛-练习集 L2-010 排座位

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <vector>
#include <cmath>

using namespace std;

const int maxn = 100 + 10;

int vis[maxn][maxn];
int pre[maxn];

int Find_Root(int x);

int main()
{
#ifdef __AiR_H
    freopen("in.txt", "r", stdin);
#endif // __AiR_H
    int N, M, K;
    scanf("%d%d%d", &N, &M, &K);
    for (int i = 1; i <= N; ++i) {
        pre[i] = i;
    }
    memset(vis, 0, sizeof(vis));
    for (int i = 0; i < M; ++i) {
        int a, b, c;
        scanf("%d%d%d", &a, &b, &c);
        vis[a][b] = vis[b][a] = c;
        if (c == 1) {
            int nx = Find_Root(a);
            int ny = Find_Root(b);
            if (nx != ny) {
                pre[nx] = ny;
            }
        }
    }
    for (int i = 0; i < K; ++i) {
        int a, b;
        scanf("%d%d", &a, &b);
        if (vis[a][b] == 1) {
            printf("No problem\n");
        } else if (vis[a][b] == 0) {
            printf("OK\n");
        } else {
            if (Find_Root(a) == Find_Root(b)) {
                printf("OK but...\n");
            } else {
                printf("No way\n");
            }
        }
    }
    return 0;
}

int Find_Root(int x)
{
    int r = x;
    while (r != pre[r]) {
        r = pre[r];
    }
    while (pre[x] != r) {
        int t = pre[x];
        pre[t] = r;
        x = t;
    }
    return r;
}

2、POJ 1611 The Suspects

#include <iostream>
#include <cstdio>

using namespace std;

const int maxn = 30000 + 5;
int pre[maxn];
int num[maxn];

int Find_Root(int x);
void Join_Union(int x, int y);

int main()
{
    int n, m;
    while (cin>>n>>m && !(n==0&&m==0)) {
        int k;
        for (int i=0; i<=n; ++i) {
            pre[i] = i;
        }
        for (int i=0; i<m; ++i) {
            cin>>k;
            for (int j=0; j<k; ++j) {
                cin>>num[j];
            }
            if (k > 1) {
                for (int j=0; j<k-1; ++j) {
                    Join_Union(num[j], num[j+1]);
                }
            }
        }
        if (m == 0) {
            cout<<n<<endl;
        } else {
            int Count = 0;
            for (int i=0; i<=n; ++i) {
                if (Find_Root(i) == 0) {
                    ++Count;
                }
            }
            cout<<Count<<endl;
        }
    }
    return 0;
}

int Find_Root(int x)
{
    int r = x;
    while (r != pre[r]) {
        r = pre[r];
    }
    while (x != r) {
        int t = pre[x];
        pre[x] = r;
        x = t;
    }
    return r;
}

void Join_Union(int x, int y)
{
    int fx = Find_Root(x);
    int fy = Find_Root(y);
    if (fx != fy) {
        if (fx == 0) {
            pre[fy] = 0;
        } else {
            pre[fx] = fy;
        }
    }
}

3、UVa 10608 Friends

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

const int maxn = 30000 + 5;
int pre[maxn];
int Count[maxn];

int Find_Root(int x);
void Join_Union(int x, int y);

int main()
{
    int T;

    cin>>T;
    while (T--) {
        memset(Count, 0, sizeof(Count));
        int N, M;
        cin>>N>>M;
        for (int i=1; i<=N; ++i) {
            pre[i] = i;
        }
        int A, B;
        for (int i=0; i<M; ++i) {
            cin>>A>>B;
            Join_Union(A, B);
        }
        for (int i=1; i<=N; ++i) {
            ++Count[Find_Root(i)];
        }
        int Max = 0;
        for (int i=1; i<=N; ++i) {
            if (Count[i] > Max) {
                Max = Count[i];
            }
        }
        cout<<Max<<endl;
    }
    return 0;
}

int Find_Root(int x)
{
    int r = x;
    while (pre[r] != r) {
        r = pre[r];
    }
    return r;
}

void Join_Union(int x, int y)
{
    int fx = Find_Root(x);
    int fy = Find_Root(y);
    if (fx != fy) {
        pre[fx] = fy;
    }
}

#include <iostream>
#include <cstdio>

using namespace std;

const int maxn = 30000 + 5;
int pre[maxn];
int num[maxn];

int Find_Root(int x);
void Join_Union(int x, int y);

int main()
{
    int T;

    cin>>T;
    while (T--) {
        int N, M;
        cin>>N>>M;
        for (int i=1; i<=N; ++i) {
            pre[i] = i;
            num[i] = 1;
        }
        int A, B;
        for (int i=0; i<M; ++i) {
            cin>>A>>B;
            Join_Union(A, B);
        }
        int Max = 0;
        for (int i=1; i<=N; ++i) {
            if (pre[i] == i) {
                if (num[i] > Max) {
                    Max = num[i];
                }
            }
        }
        cout<<Max<<endl;
    }
    return 0;
}

int Find_Root(int x)
{
    int r = x;
    while (pre[r] != r) {
        r = pre[r];
    }
    while (x != r) {
        int t = pre[x];
        pre[x] = r;
        x = t;
    }
    return r;
}

void Join_Union(int x, int y)
{
    int fx = Find_Root(x);
    int fy = Find_Root(y);
    if (fx != fy) {
        pre[fx] = fy;
        num[fy] += num[fx];
    }
}

4、NUC_第11届校赛_B 多线程并发

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <map>
#include <queue>
#include <algorithm>

using namespace std;

const int INF = 0x3f3f3f3f;

const int maxn = 100000 + 10;
int pre[maxn];
int N, M;
int num[maxn];
int ans[maxn];

int Find_Root(int x);

int main()
{
    scanf("%d%d", &N, &M);
    int A, B;
    for (int i = 1; i <= N; ++i) {
        pre[i] = i;
        num[i] = 1;
    }
    int Max = 0;
    int t;
    for (int i = 0; i < M; ++i) {
        scanf("%d%d", &A, &B);
        int nx = Find_Root(A);
        int ny = Find_Root(B);
        if (nx != ny) {
            pre[nx] = ny;
            num[ny] += num[nx];
            if (num[ny] > Max) {
                Max = num[ny];
                t = ny;
            }
        }
    }
    int Count = 0;
    for (int i = 1; i <= N; ++i) {
        if (Find_Root(i) == t) {
            ans[Count] = i;
            ++Count;
        }
    }
    sort(ans, ans+Count);
    printf("%d\n", Count);
    printf("%d", ans[0]);
    for (int i = 1; i < Count; ++i) {
        printf(" %d", ans[i]);
    }
    printf("\n");
    return 0;
}

int Find_Root(int x)
{
    int r = x;
    while (pre[r] != r) {
        r = pre[r];
    }
    while (r != x) {
        int t = pre[x];
        pre[x] = r;
        x = t;
    }
    return r;
}

5、团队程序设计天梯赛-练习集-L2-007 家庭房产

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <cmath>
#include <cctype>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;

const double eps = 1e-8;
const ull mod = 1e9 + 7;
const int INF = 0x7fffffff;
const int maxn = 1e4 + 10;
int N;

struct Node {
    int people, house, area;
};

struct Ans {
    int name, num;
    double average_house, average_area;
};

Node node[maxn];
int pre[maxn];
int key[1010];
bool vis[maxn];
Ans ans[1010];
int Count = 0;

int Find_Root(int x);
int cmp(const void* a, const void* b);

int main()
{
#ifdef __AiR_H
    freopen("in.txt", "r", stdin);
#endif // __AiR_H
    scanf("%d", &N);
    memset(node, 0, sizeof(node));
    for (int i = 0; i < maxn; ++i) {
        node[i].people = 1;
    }
    for (int i = 0; i < maxn; ++i) {
        pre[i] = i;
    }
    int k;
    int t, guy, area, house;
    for (int i = 0; i < N; ++i) {
        queue<int> Queue;
        for (int j = 0; j < 3; ++j) {
            scanf("%d", &t);
            if (t != -1) {
                Queue.push(t);
            }
        }
        scanf("%d", &k);
        for (int j = 0; j < k; ++j) {
            scanf("%d", &guy);
            if (guy != -1) {
                Queue.push(guy);
            }
        }
        scanf("%d%d", &house, &area);
        int f = Queue.front();
        key[i] = f;
        int r = Find_Root(f);
        node[r].house += house; node[r].area += area;
        Queue.pop();
        while (!Queue.empty()) {
            int rx = Find_Root(f), ry = Find_Root(Queue.front());
            if (rx != ry) {
                if (rx <= ry) {
                    pre[ry] = rx;
                    node[rx].people += node[ry].people; node[rx].area += node[ry].area; node[rx].house += node[ry].house;
                } else {
                    pre[rx] = ry;
                    node[ry].people += node[rx].people; node[ry].area += node[rx].area; node[ry].house += node[rx].house;
                }
            }
            Queue.pop();
        }
    }

    memset(vis, false, sizeof(vis));
    for (int i = 0; i < N; ++i) {
        int r = Find_Root(key[i]);
        if (!vis[r]) {
            vis[r] = true;
            ans[Count].name = r;
            ans[Count].num = node[r].people;
            ans[Count].average_house = node[r].house * 1.0 / node[r].people;
            ans[Count].average_area = node[r].area * 1.0 / node[r].people;
            ++Count;
        }
    }
    printf("%d\n", Count);
    qsort(ans, Count, sizeof(ans[0]), cmp);
    for (int i = 0; i < Count; ++i) {
        printf("%04d %d %.3f %.3f\n", ans[i].name, ans[i].num, ans[i].average_house, ans[i].average_area);
    }
    return 0;
}

int Find_Root(int x)
{
    int r = x;
    while (pre[r] != r) {
        r = pre[r];
    }
    while (pre[x] != r) {
        int t = pre[x];
        pre[x] = r;
        x = t;
    }
    return r;
}

int cmp(const void* a, const void* b)
{
    Ans* x = (Ans*)a;
    Ans* y = (Ans*)b;
    if (x->average_area == y->average_area) {
        return (x->name - y->name) < 0 ? -1 : 1;
    }
    return (x->average_area - y->average_area) < 0 ? 1 : -1;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值