[SCOI2010]游戏
思路
很容易看出这是一个二分图匹配问题,对于每一种属性,我们必须找到一个与之可以相应匹配的物品,所以我们建立的两条边,然后从开始匹配,当遇到第一个无法匹配的属性时我们即可输出答案,因为题目要求所有的攻击必选是连续递增的属性。
代码
/* Author : lifehappy */ #pragma GCC optimize(2) #pragma GCC optimize(3) #include <bits/stdc++.h> #define mp make_pair #define pb push_back #define endl '\n' #define mid (l + r >> 1) #define lson rt << 1, l, mid #define rson rt << 1 | 1, mid + 1, r #define ls rt << 1 #define rs rt << 1 | 1 using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<int, int> pii; const double pi = acos(-1.0); const double eps = 1e-7; const int inf = 0x3f3f3f3f; inline ll read() { ll f = 1, x = 0; char c = getchar(); while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); } while(c >= '0' && c <= '9') { x = (x << 1) + (x << 3) + (c ^ 48); c = getchar(); } return f * x; } const int N = 1e6 + 10; int head[N], to[N << 1], nex[N << 1], cnt = 1; int match[N], n; bool visit[N]; void add(int x, int y) { to[cnt] = y; nex[cnt] = head[x]; head[x] = cnt++; } bool find(int rt) { for(int i = head[rt]; i; i = nex[i]) { if(!visit[to[i]]) { visit[to[i]] = 1; if(!match[to[i]] || find(match[to[i]])) { match[to[i]] = rt; return true; } } } return false; } int main() { // freopen("in.txt", "r", stdin); // freopen("out.txt", "w", stdout); // ios::sync_with_stdio(false), cin.tie(0), cout.tie(0); n = read(); for(int i = 1; i <= n; i++) { int x = read(), y = read(); add(x, i); add(y, i); } for(int i = 1; i < N; i++) { memset(visit, 0, sizeof visit); if(!find(i)) { printf("%d\n", i - 1); return 0; } } return 0; }