bzoj1854 [Scoi2010]游戏——匈牙利算法

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1854

这题...据说可以用并查集做,但没有去看...

用二分图匹配的话,就把装备和它的两个属性连边,再从属性开始从小到大进行匈牙利算法;

这样可以保证匹配这个属性时先确保前面的都匹配成功了;

所以遇到无法匹配的情况时就结束了,输出即可;

小心TLE,所以避免 memset。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int const maxn=1000005,maxm=10005;
int n,head[maxm],ct,pre[maxn],mx,ans;
int vis[maxn];
struct N{
    int to,next;
    N(int t=0,int n=0):to(t),next(n) {}
}edge[maxn<<1];
void add(int x,int y){edge[++ct]=N(y,head[x]); head[x]=ct;}
bool dfs(int x)
{
    for(int i=head[x],u;i;i=edge[i].next)
    {
        if(vis[u=edge[i].to]!=ans)
//        if(!vis[u=edge[i].to])//TLE!
        {
            vis[u]=ans;
            if(!pre[u]||dfs(pre[u]))
            {
                pre[u]=x; return 1;
            }
        }
    }
    return 0;
}
int main()
{
    scanf("%d",&n);
    for(int i=1,x,y;i<=n;i++)
    {
        scanf("%d%d",&x,&y);
        add(x,i); add(y,i);
        mx=max(mx,max(x,y));
    }
    for(int i=1;i<=mx;i++)
    {
//        memset(vis,0,sizeof vis);//TLE!
        ans++;
        if(!dfs(i))
        {
            printf("%d\n",ans-1); return 0;
        }
    }
    printf("%d",ans);
    return 0;
}

原文地址:https://www.cnblogs.com/Zinn/p/9208122.html

时间: 2024-08-03 12:06:43

bzoj1854 [Scoi2010]游戏——匈牙利算法的相关文章

bzoj1854: [Scoi2010]游戏(匈牙利) / GDKOI Day2 T2(最大流)

题目大意:有n(<=1000000)个装备,每个装备有两个属性值(<=10000),每个装备只能用一次,使用某一个值,攻击boss必须先使用属性为1的,再使用属性为2的,再使用属性为3的,以此类推······问最多攻击多少次. 每个武器和他的两个属性值连边,跑匈牙利. 学会了新的技巧,可以省掉1w个memset(这题是真·1w个 2333333). 代码如下: #include<iostream> #include<cstdlib> #include<cstrin

[蒟蒻修炼计划][bzoj1854][SCOI2010]游戏

Description 一个装备有两个属性,一个装备只能被使用一次,一次使用一种属性.攻击boss时需按属性1.属性2.属性3...属性k的顺序使用,问k最大为多少. Input 输入的第一行是一个整数N,表示有N种装备.接下来N行,是对这N种装备的描述,每行2个数字,表示第i种装备的2个属性值. Output 输出一行,包括1个数字,表示k. Sample Input 3 1 2 3 2 4 5 Sample Output 2 HINT 1<=属性值<=10000,N < =10000

BZOJ1854: [Scoi2010]游戏

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1854 题目大意:lxhgww最近迷上了一款游戏,在游戏里,他拥有很多的装备,每种装备都有2个属性,这些属性的值用[1,10000]之间的数表示.当他使用某种装备时,他只能使用该装备               的某一个属性.并且每种装备最多只能使用一次. 游戏进行到最后,lxhgww遇到了终极boss,这个终极boss很奇怪,攻击他的装备所使用的属性值必须从1开始连续递增        

[BZOJ1854][Scoi2010]游戏(二分图匹配/并查集)

题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1854 分析:很裸的一道二分图匹配对吧,但是在hzwer的blog上看见神奇的并查集做法! 其实这题和bzoj1191惊人的相似! 把权值当作点,装备当作边,既然一个装备只能选择一个属性,也就是你要人为给边定向,箭头指到的点就表示你这个装备选的属性. 然后就和bzoj1191一样的了 如果一个集合里的点构成一个树,那么很显然,把那个权值最大的点作为根,除了根节点以外的点都可以选出,如果

[SCOI2010][BZOJ1854] 游戏|二分图匹配|匈牙利算法|并查集

1854: [Scoi2010]游戏 Time Limit: 5 Sec  Memory Limit: 162 MBSubmit: 3018  Solved: 1099[Submit][Status][Discuss] Description lxhgww最近迷上了一款游戏,在游戏里,他拥有很多的装备,每种装备都有2个属性,这些属性的值用[1,10000]之间的数表示.当他使用某种装备时,他只能使用该装备的某一个属性.并且每种装备最多只能使用一次. 游戏进行到最后,lxhgww遇到了终极boss

矩阵游戏|ZJOI2007|BZOJ1059|codevs1433|luoguP1129|二分图匹配|匈牙利算法|Elena

1059: [ZJOI2007]矩阵游戏 Time Limit: 10 Sec  Memory Limit: 162 MB Description 小Q是一个非常聪明的孩子,除了国际象棋,他还很喜欢玩一个电脑益智游戏--矩阵游戏.矩阵游戏在一个N *N黑白方阵进行(如同国际象棋一般,只是颜色是随意的).每次可以对该矩阵进行两种操作:行交换操作:选择 矩阵的任意两行,交换这两行(即交换对应格子的颜色)列交换操作:选择矩阵的任意行列,交换这两列(即交换 对应格子的颜色)游戏的目标,即通过若干次操作,

BZOJ1443 游戏game (二分图染色+匈牙利算法)

先对整幅图进行二分图染色,再跑一遍匈牙利算法.如果最大匹配数=点数*2,那么输出WIN. 对于任何一个非必须在最大匹配上的点,即为所求的点. 1 Program Test375num2; 2 type arr=record 3 u,v,next:longint; 4 end; 5 const dx:array[1..4] of longint=(0,0,-1,1); 6 dy:array[1..4] of longint=(1,-1,0,0); 7 maxn=100008; 8 maxm=max

bzoj 1059: [ZJOI2007]矩阵游戏【匈牙利算法】

注意到怎么换都行,但是如果把某个黑方块用在对角线上,它原来所在的行列的的黑方块就都不能用 所以要选出n组不重的行列组合,这里用匈牙利算法做二分图匹配即可(用了时间戳优化) #include<iostream> #include<cstdio> #include<cstring> using namespace std; const int N=405; int T,n,cnt,h[N],lk[N],v[N],ti; struct qwe { int ne,to; }e[

BZOJ 1854: [Scoi2010]游戏( 二分图最大匹配 )

匈牙利算法..从1~10000依次找增广路, 找不到就停止, 输出答案. ---------------------------------------------------------------------------- #include<bits/stdc++.h> using namespace std; const int MAXL = 10009, MAXR = 1000009; struct edge { int to; edge* next; } E[MAXR <<