题面:
题解:
不看标签还是很难想到建图,看了标签也想不到怎么建图。
因为每个数字只能被选择一次,每个装备也只能被选择一次,那么就可以考虑装备与两个属性之间建边。
那么问题就变成了二分图最大匹配问题。
从1开始匹配,知道匹配不上为止。
但是有一个细节,原本的匹配算法需要每次匹配时 m e m s e t memset memset 数组,但是这里不能 ,会 T L E TLE TLE ,需要用一个时间戳记录一下。
代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<unordered_map>
#include<map>
#include<stack>
#include<set>
#include<ctime>
#define iss ios::sync_with_stdio(false)
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
typedef pair<int,int> pii;
const int mod=1e9+7;
const int MAXN=2e5+5;
const int inf=0x3f3f3f3f;
vector<int> g[MAXN];
int vis[MAXN],tim,match[MAXN];
int find(int x)
{
for(auto i:g[x]){
if(vis[i]!=tim){
vis[i] = tim;
if(!match[i]||find(match[i])){
match[i] = x;
return 1;
}
}
}
return 0;
}
int main()
{
int n;
scanf("%d", &n);
for (int i = 1; i <= n;i++){
int a, b;
scanf("%d%d", &a, &b);
g[a].push_back(i);
g[b].push_back(i);
}
int ans = 0;
for (int i = 1; i <= 10000;i++){
tim++;
if(find(i)){
ans++;
}
else{
break;
}
}
printf("%d\n", ans);
}