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
  • 相关阅读:
    String.Intern原来可以减少占用内存···
    一些话···
    javascript 闭包和原型 (转载)
    20100610
    jQuery选择头像
    20100611
    新的一天又开始了····
    13种常用按钮、文本框、表单等CSS样式
    心悸···
    我对她说,你能不能换件衣服?换种心情?换种脾气?她说,可以,换个人就行了···
  • 原文地址:https://www.cnblogs.com/19992147orz/p/7462599.html
Copyright © 2011-2022 走看看