SCOI省选题。
第一种做法是二分图匹配,即属性向装备连边,一旦不能匹配输出即可。
第二种做法是并查集。装备当作边连接两个点,如果某x条边没有环,它最大那个一定找不到属于自己的边。因此一旦某个点所在并查集中无环且最大的点是自己那么就可以输出答案了。
都很短。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define maxl 5050
#define maxr 2000050
#define maxe 5000050
using namespace std;
struct edge
{
int v,nxt;
}e[maxe];
int n,g[maxr],x,y,linker[maxr],nume=0,cnt=0;
int used[maxr];
void addedge(int u,int v)
{
e[++nume].v=v;
e[nume].nxt=g[u];
g[u]=nume;
}
bool dfs(int u)
{
for (int i=g[u];i;i=e[i].nxt)
{
int v=e[i].v;
if (used[v]==cnt) continue;
used[v]=cnt;
if ((linker[v]==-1)||(dfs(linker[v])==true))
{
linker[v]=u;
return true;
}
}
return false;
}
int main()
{
memset(g,0,sizeof(g));
memset(linker,-1,sizeof(linker));
memset(used,0,sizeof(used));
scanf("%d",&n);
for (int i=1;i<=n;i++)
{
scanf("%d%d",&x,&y);
addedge(x,i);
addedge(y,i);
}
int rec=0;
for (int i=1;i<=10000;i++)
{
cnt++;
if (dfs(i)==true) rec++;
else break;
}
printf("%d\n",rec);
return 0;
}