zoukankan      html  css  js  c++  java
  • P1640 [SCOI2010]连续攻击游戏 匈牙利算法

      

    题目描述

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

    输入输出格式

    输入格式:

    输入的第一行是一个整数N,表示lxhgww拥有N种装备接下来N行,是对这N种装备的描述,每行2个数字,表示第i种装备的2个属性值

    输出格式:

    输出一行,包括1个数字,表示lxhgww最多能连续攻击的次数。

    输入输出样例

    输入样例#1: 复制
    3
    1 2
    3 2
    4 5
    
    输出样例#1: 复制
    2

    说明

    Limitation

    对于30%的数据,保证N < =1000

    对于100%的数据,保证N < =1000000

    左图为装备  右图为boss

    然后从boss的1开始遍历  如果匹配不到  那么就return  因为匈牙利是满足之前全部匹配好的!!

    二分匹配也恰好满足 左边装备两个属性只能用一次

    还有一个wa点是     有两个点死活TLE

    可以增加时间戳标记   这样就不用一直memset used了    跑的飞快

    #include<bits/stdc++.h>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m)
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s);
    #define ll long long
    #define pb push_back
    #define REP(i,N)  for(int i=0;i<(N);i++)
    #define CLR(A,v)  memset(A,v,sizeof A)
    //////////////////////////////////
    #define inf 0x3f3f3f3f
    const int N=1000000+5;
    const int M=2000000+5;
    int head[M],pos,n,m,flag;
    struct Edge
    {
        int nex,to;
    }edge[M];
    void add(int a,int b)
    {
        edge[++pos].nex=head[a];
        head[a]=pos;
        edge[pos].to=b;
    }
    int vis[N],used[N];
    
    bool dfs(int x)
    {
    
        for(int i=head[x];i;i=edge[i].nex)
        {
            int v=edge[i].to;
            if(flag!=used[v])
            {
                used[v]=flag;
                if(!vis[v]||dfs(vis[v]))
                {
                    vis[v]=x;
                    return true;
                }
            }
    
        }
        return false;
    }
    
    int find1()
    {
        int ans=0;
        rep(i,1,10000)
        {
            flag++;//用时间戳大大加速
            if(dfs(i))ans++;
            else return ans;
        }
        return ans;
    }
    
    int main()
    {
        RI(n);
        rep(i,1,n)
        {
            int a,b;RII(a,b);
            add(a,i);
            add(b,i);
        }
        printf("%d",find1());
    }
    View Code

    并查集:

  • 相关阅读:
    javaScript中eval()方法转换json对象
    JS 根据参数是否为空进行true|false判断呢
    mybatis返回map类型数据空值字段不显示(三种解决方法)
    值类型与引用类型的区别
    随机生成四位数字和字母
    彩票
    冒泡排序
    查询资料:二分查找法
    随机数生成机制
    运算符
  • 原文地址:https://www.cnblogs.com/bxd123/p/10819672.html
Copyright © 2011-2022 走看看