• 洛谷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

    来源:SCOI 2010

     题解

      二分图

      然而坑爹的是并不能用网络流,只能用匈牙利跑(毕竟我基本不会匈牙利)

      考虑怎么建图

      对于每一个属性,我们把它向拥有这一个属性的编号连边

      每一个编号不可能提供超过一个属性,每一个属性也不可能来自多于一个编号

      所以每一次从对应的属性的点跑匈牙利,如果找不到增广路说明gg了

      然后每一次都重置vis数组太慢了,用时间戳记录比较好

     1 //minamoto
     2 #include<iostream>
     3 #include<cstdio>
     4 #include<cstring>
     5 using namespace std;
     6 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
     7 char buf[1<<21],*p1=buf,*p2=buf;
     8 inline int read(){
     9     #define num ch-'0'
    10     char ch;bool flag=0;int res;
    11     while(!isdigit(ch=getc()))
    12     (ch=='-')&&(flag=true);
    13     for(res=num;isdigit(ch=getc());res=res*10+num);
    14     (flag)&&(res=-res);
    15     #undef num
    16     return res;
    17 }
    18 const int N=1000005;
    19 int head[N],Next[N<<1],ver[N<<1],Pre[N],vis[N],tot;
    20 int n,ans;
    21 inline void add(int u,int v){
    22     ver[++tot]=v,Next[tot]=head[u],head[u]=tot;
    23 }
    24 bool dfs(int u,int tm){
    25     if(vis[u]==tm) return false;
    26     vis[u]=tm;
    27     for(int i=head[u];i;i=Next[i]){
    28         int v=ver[i];
    29         if(!Pre[v]||dfs(Pre[v],tm)){
    30             Pre[v]=u;return true;
    31         }
    32     }
    33     return false;
    34 }
    35 int main(){
    36     n=read();
    37     for(int i=1;i<=n;++i){
    38         int u=read(),v=read();
    39         add(u,i),add(v,i);
    40     }
    41     for(int i=1;;++i){
    42         if(dfs(i,i)) ++ans;
    43         else return printf("%d
    ",ans),0;
    44     }
    45     return 0;
    46 }
  • 相关阅读:
    [ARC117F]Gateau
    [ARC117D]Miracle Tree
    [loj3504]支配
    [gym102511K]Traffic Blights
    [loj3501]图函数
    [loj3503]滚榜
    [loj3500]矩阵游戏
    [loj2135]幻想乡战略游戏
    [cf720D]Slalom
    [cf1349E]Slime and Hats
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/9513472.html
Copyright © 2020-2023  润新知