题目链接:BZOJ 1854
这道题也可以用神奇的并查集做,但是由于我的脑洞不够大,所以就用的二分图匹配。但是直接暴力二分图匹配多次memset会TLE,所以每次标记vis只需记录它上次匹配的编号。
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
#define maxn (1010000+5)
int N,T=0;
int head[maxn],belong[maxn],vis[maxn];
struct node{
int v,next;
}e[2*maxn];
int k=0;
void adde(int u,int v){
e[++k].v=v; e[k].next=head[u]; head[u]=k;
}
bool find(int x){
for(int i=head[x];i!=-1;i=e[i].next){
int v=e[i].v;
if(vis[v]!=T){
vis[v]=T;
if(!belong[v]||find(belong[v])){
belong[v]=x; return true;
}
}
}
return false;
}
int main(){
memset(head,-1,sizeof(head));
scanf("%d",&N);
for(int i=1;i<=N;i++){
int x,y;
scanf("%d%d",&x,&y);
adde(x,i); adde(y,i);
}
int tot=0;
for(int i=1;i<=10000;i++){
T++;
if(find(i))tot++;
else break;
}
printf("%d",tot);
return 0;
}