zoukankan      html  css  js  c++  java
  • 【刷题】【二分图】【并查集】

    题目:

    lxhgww最近迷上了一款游戏,在游戏里,他拥有很多的装备,每种装备都有2个属性,这些属性的值用[1,10000]之间的数表示。当他使用某种装备时,他只能使用该装备的某一个属性。并且每种装备最多只能使用一次。 游戏进行到最后,lxhgww遇到了终极boss,这个终极boss很奇怪,攻击他的装备所使用的属性值必须从1开始连续递增地攻击,才能对boss产生伤害。也就是说一开始的时候,lxhgww只能使用某个属性值为1的装备攻击boss,然后只能使用某个属性值为2的装备攻击boss,然后只能使用某个属性值为3的装备攻击boss……以此类推。 现在lxhgww想知道他最多能连续攻击boss多少次?

    【1】二分图

    属性是左集合,武器是右集合,然后二分图

    复杂度O(n*n)

    【2】并查集

    (https://blog.csdn.net/zp1ng/article/details/79006544)

    把每个属性当作一个点,武器是连边。

    当一个节点数是n的联通块是一棵树时,只有n-1个属性能被满足;当联通快不是一棵树时,所有的属性都能被满足。

    所以把每个联通快用并查集维护,当联通块是一棵树的时候让块内最大的属性值不能满足。最后暴力查结果就可以了。

    #include<iostream>
    #include<cstdlib>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<algorithm>
    #include<cmath>
    #include<map>
    #include<vector>
    #define N 1000005
    using namespace std;
    int n,fa[N];
    bool vi[N];
    int find(int x)
    {
        if(fa[x]==x) return x;
        return fa[x]=find(fa[x]);
    }
    void hb(int x,int y)
    {
        int a=find(x),b=find(y);
        if(a>b)swap(a,b);
        if(a==b) vi[a]=1;
        else
        {
            if(!vi[a]) vi[a]=1;
            else vi[b]=1;
            fa[a]=b;
        }
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=10000;i++)
            fa[i]=i;
        for(int i=1;i<=n;i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            hb(x,y);
        }
        for(int i=1;i<=10001;i++)
            if(!vi[i])
            {
                printf("%d
    ",i-1);
                break;
            }
        return 0;
    }
  • 相关阅读:
    Android与js交互实例
    动态规划-最长公共子序列
    android调用js
    比特币不是虚拟货币,这是一个真实世界----李笑来
    Linux进程同步之POSIX信号量
    编程至死第0天
    JMX操作ActiveMQ(2)
    Oracle层次查询和with函数的使用
    boost::asio async_write也不能保证一次发完所有数据 一
    解决Eclipse一直loading workbench无法启动的问题
  • 原文地址:https://www.cnblogs.com/xwww666666/p/11832862.html
Copyright © 2011-2022 走看看