|
|
#include <bits/stdc++.h>
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
const int N = 2e5 + 10;
|
|
|
int n, k;
|
|
|
int x[N], y[N];
|
|
|
|
|
|
struct Node {
|
|
|
int to, id; // id:哪个房间,to:另一只猫猫的号码
|
|
|
};
|
|
|
|
|
|
vector<Node> g[N];
|
|
|
vector<int> S;
|
|
|
bool st[N];
|
|
|
|
|
|
// void getnodes(int u) {
|
|
|
// st[u] = 1;
|
|
|
// S.push_back(u);
|
|
|
// for (auto e : g[u]) {
|
|
|
// int v = e.to;
|
|
|
// if (!st[v]) getnodes(v);
|
|
|
// }
|
|
|
// }
|
|
|
|
|
|
vector<int> C;
|
|
|
int fa[N], pre[N], res[N];
|
|
|
bool fi;
|
|
|
|
|
|
void findcycle(int u) {
|
|
|
st[u] = 1; // u号小猫已经找过房间了
|
|
|
for (auto e : g[u]) { // 遍历u号小猫的每个可用房间
|
|
|
int v = e.to, i = e.id;
|
|
|
if (i == pre[u]) continue; // 不走回头路
|
|
|
|
|
|
if (!st[v]) { // 进入搜索
|
|
|
fa[v] = u, pre[v] = i, findcycle(v);
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
if (fi) continue;
|
|
|
int q = u;
|
|
|
while (q != v) {
|
|
|
C.push_back(q), res[pre[q]] = (x[pre[q]] == q ? 2 : 1);
|
|
|
q = fa[q];
|
|
|
}
|
|
|
res[i] = (x[i] == u ? 1 : 2);
|
|
|
fi = 1;
|
|
|
C.push_back(v);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
bool chk(int m) {
|
|
|
// 多次二分,清空现场
|
|
|
for (int i = 1; i <= n; i++) g[i].clear();
|
|
|
memset(st, 0, sizeof(st)), memset(pre, 0, sizeof(pre)), memset(fa, 0, sizeof(fa));
|
|
|
|
|
|
// 前m个房间
|
|
|
for (int i = 1; i <= m; i++) {
|
|
|
int u = x[i], v = y[i];
|
|
|
// 无向图建图
|
|
|
g[u].push_back({v, i}); // u这只猫猫,可以使用i这个房间,另外一个可以使用i房间的猫猫是v号
|
|
|
g[v].push_back({u, i}); // v这只猫猫,可以使用i这个房间,另外一个可以使用i房间的猫猫是u号
|
|
|
}
|
|
|
|
|
|
for (int i = 1; i <= n; i++) { // 每只猫
|
|
|
if (st[i]) continue; // 如果访问过,就下一个
|
|
|
fi = 0, C.clear(); // fi:i号小猫在哪个房间里?
|
|
|
findcycle(i); // 为i号小猫找房间
|
|
|
if (!fi) return 0; // 如果没有找到合适的房间,那么就表示当前的m太小的,需要扩大
|
|
|
}
|
|
|
return 1; // 检查通过,返回OK
|
|
|
}
|
|
|
|
|
|
void dfs(int u) {
|
|
|
st[u] = 1;
|
|
|
for (auto e : g[u]) {
|
|
|
int v = e.to, i = e.id;
|
|
|
if (st[v] || res[i] != 0) continue;
|
|
|
res[i] = (x[i] == v ? 1 : 2);
|
|
|
dfs(v);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// void getans(int m) {
|
|
|
// for (int i = 1; i <= n; i++) g[i].clear();
|
|
|
// memset(st, 0, sizeof(st)), memset(pre, 0, sizeof(pre));
|
|
|
// memset(fa, 0, sizeof(fa)), memset(res, 0, sizeof(res));
|
|
|
|
|
|
// for (int i = 1; i <= m; i++) {
|
|
|
// int u = x[i], v = y[i];
|
|
|
// g[u].push_back({v, i}), g[v].push_back({u, i});
|
|
|
// }
|
|
|
|
|
|
// for (int i = 1; i <= n; i++) {
|
|
|
// if (st[i]) continue;
|
|
|
// S.clear();
|
|
|
// getnodes(i);
|
|
|
// fi = 0;
|
|
|
// for (int p : S) st[p] = 0;
|
|
|
// C.clear();
|
|
|
// findcycle(i);
|
|
|
// for (int p : S) st[p] = 0;
|
|
|
// for (int p : C) st[p] = 1;
|
|
|
// for (int p : C) dfs(p);
|
|
|
// for (int p : S) st[p] = 1;
|
|
|
// }
|
|
|
|
|
|
// for (int i = 1; i <= m; i++) cout << res[i] << " ";
|
|
|
// puts("");
|
|
|
// }
|
|
|
|
|
|
int main() {
|
|
|
freopen("cats.in", "r", stdin);
|
|
|
// freopen("cats.out", "w", stdout);
|
|
|
|
|
|
cin >> n >> k; // n只小猫,k个房间
|
|
|
for (int i = 1; i <= k; i++) cin >> x[i]; // k个房间,可以容纳x[i]的猫猫
|
|
|
for (int i = 1; i <= k; i++) cin >> y[i]; // k个房间,可以容纳y[i]的猫猫
|
|
|
|
|
|
int L = 1, R = k, ans = L; // 二分答案
|
|
|
while (L <= R) {
|
|
|
int mid = (L + R) >> 1;
|
|
|
if (chk(mid)) // 如果每个猫猫都可以有房间,那么检查通过,说明房间的数量还是很宽松的
|
|
|
R = mid - 1, ans = mid;
|
|
|
else
|
|
|
L = mid + 1;
|
|
|
}
|
|
|
|
|
|
// 输出数量
|
|
|
cout << ans << endl;
|
|
|
|
|
|
// 输出方案
|
|
|
// getans(ans);
|
|
|
|
|
|
return 0;
|
|
|
} |