zoukankan      html  css  js  c++  java
  • bzoj1854

    二分图匹配/并查集

    其实我们发现,这里的方案就是希望从一开始一直能够被匹配上,那么我们就设立1-10000个点,一个装备向对应的属性连边,那么我们从1开始跑匹配,直到不能匹配结束。

    但是这样很明显不是正解,我们把每个装备的两个属性之间连边,把小的属性连向大的属性,如果这两个属性已经相连,那么我们把大的属性赋值访问过,否则相连,把小的属性赋值相连,然后就是统计答案,我们找到第一个未访问的点i,答案就是i-1

    原理是什么呢?引用hzwer

    将每个武器变成一条边 连接两个属性

    如果一个联通块形成了一棵n个点的树 那么只能满足其中的n-1个的点

    如果一个联通块有一个环 那么就能满足所有的点

    于是我们用并查集维护图的连通性,对于每个集合记录这个联通块有没有环,以及这个联通块中最大的点是多少

    一旦某个点所在并查集中无环且最大的点是自己那么就可以输出答案了

    一个联通块里如果没有环,那么最大的不能选,否则都能选,正确性显然,vis记录是否能选

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 1000010; 
    int n;
    int fa[N], vis[N];
    inline int find(int x) { return x == fa[x] ? x : fa[x] = find(fa[x]); }
    int main()
    {
        scanf("%d", &n);
        for(int i = 1; i <= 10000; ++i) fa[i] = i;
        for(int i = 1; i <= n; ++i)
        {
            int u, v, x, y;
            scanf("%d%d", &u, &v);
            x = find(u);
            y = find(v);
            if(x == y) vis[x] = 1;
            else
            {
                if(x < y) swap(x, y);
                vis[y] = 1;
                fa[y] = x;
            }
        }
        for(int i = 1; i <= 10001; ++i) if(!vis[i])
        {
            printf("%d
    ", i - 1);
            return 0;
        }
        return 0;
    } 
    View Code
  • 相关阅读:
    缓存穿透、缓存并发和缓存雪崩笔记
    PHP递归的三种方式
    Yii2 rules 自定义规则
    Yii redis hash散列的使用
    Yii redis set集合的使用
    手动安装 yii2-redis 扩展
    PHP添加redis扩展(windows环境)
    Yii redis list列表的使用
    用hextoraw解决update、delete语句执行慢
    Oracle查看SQL执行计划,分析SQL性能
  • 原文地址:https://www.cnblogs.com/19992147orz/p/7462599.html
Copyright © 2011-2022 走看看