题目链接
http://www.lydsy.com/JudgeOnline/problem.php?id=1854
思路
注意到每个属性只能对应一个武器(选择的属性必须递增),每个武器只能选择一个属性,这东西像什么?二分图!
实际上就是一个很裸的二分图匹配问题,我们把每个武器向它所属的两个属性连边,从属性1开始依次对每个属性作起点跑二分图匹配,直到某个属性
i
跑不出匹配,退出循环,答案就是
代码
蒟蒻二分图匹配居然都能写错两个地方,这玩意都能写错,贡献好多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;
}