[BZOJ 1854][SCOI 2010]游戏(二分图最大匹配)

题目链接

http://www.lydsy.com/JudgeOnline/problem.php?id=1854

思路

注意到每个属性只能对应一个武器(选择的属性必须递增),每个武器只能选择一个属性,这东西像什么?二分图!
实际上就是一个很裸的二分图匹配问题,我们把每个武器向它所属的两个属性连边,从属性1开始依次对每个属性作起点跑二分图匹配,直到某个属性 i 跑不出匹配,退出循环,答案就是 i1

代码

蒟蒻二分图匹配居然都能写错两个地方,这玩意都能写错,贡献好多WA,我是粗心大意的二货。。。。

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>

#define MAXN 5000000

using namespace std;

int vis[MAXN]; //访问标记
int T=0;

struct edge
{
    int u,v,next;
}edges[MAXN];

int head[MAXN],nCount=0;

void AddEdge(int U,int V)
{
    edges[++nCount].u=U;
    edges[nCount].v=V;
    edges[nCount].next=head[U];
    head[U]=nCount;
}

int pre[MAXN];

bool DFS(int u)
{
    for(int p=head[u];p!=-1;p=edges[p].next)
    {
        int v=edges[p].v;
        if(vis[v]!=T) //!!!!!这个点没访问过
        {
            vis[v]=T;
            if(!pre[v]||DFS(pre[v])) //!!!!!我是SB,二分图匹配这玩意都能写错!!
            {
                pre[v]=u;
                return true;
            }
        }
    }
    return false;
}

int main()
{
    memset(head,-1,sizeof(head));
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        int skilla,skillb;
        scanf("%d%d",&skilla,&skillb);
        AddEdge(skilla+n,i);
        AddEdge(skillb+n,i);
    }
    for(int i=1;i<=20000;i++)
    {
        T++;
        if(!DFS(i+n))
        {
            printf("%d\n",i-1);
            return 0;
        }
    }
    return 0;
}

你可能感兴趣的:([BZOJ 1854][SCOI 2010]游戏(二分图最大匹配))