You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

96 lines
2.7 KiB

2 years ago
#include <bits/stdc++.h>
using namespace std;
// TODO 只过了两个测试点,因为没有测试数据,所以不知道为什么,两个样例都是可以过的
// 2023-03-20
// 对拍也不知道怎么做一会问一下ChatGpt
// 明天研究一下对拍https://www.cnblogs.com/EdisonBa/p/13509379.html
const int N = 2e5 + 10, M = N << 1;
int n, k; // 猫猫数量,房间总数
int x[N], y[N]; // i:第几个房间,x[i]:可以住哪只猫猫,y[i]:可以住哪只猫猫
// 链式前向星
int e[M], h[N], idx, w[M], ne[M];
void add(int a, int b, int c = 0) {
e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++;
}
int st[M]; // 房间是不是使用过
int flag; // 所有猫猫是不是都有了房间
int out;
vector<int> path;
// 树+dfs搜索
void dfs(int u, int m) {
if (u == n + 1) {
flag = 1;
if (!out) {
// 记录最新获得的结果
path.clear();
for (int i = 1; i <= m; i++) {
if (st[i] == x[i])
path.push_back(1);
else
path.push_back(2);
}
out = 1;
}
return;
}
for (int i = h[u]; ~i; i = ne[i]) {
int room = w[i]; // 哪个房间
if (st[room]) continue; // 如果这个房间用人用了,就不能用
// 记录
st[room] = u; // 记录这个房间谁在用
// 递归
dfs(u + 1, m);
// 回溯
st[room] = 0;
}
}
bool chk(int m) {
// 清空
memset(h, -1, sizeof h);
idx = 0;
flag = 0;
out = 0;
memset(st, 0, sizeof st);
for (int i = 1; i <= m; i++) { // 前m个房间
add(x[i], y[i], i); // 将房间号作为边权理解为x[i]号小猫可以用掉这个与它相连的房间y[i]号小猫也可以用掉这个与它相边的房间
add(y[i], x[i], i);
}
// 检查一下现在可以满足每个小猫都有房间住吗?
dfs(1, m);
return flag;
}
int main() {
freopen("cats.in", "r", stdin);
// freopen("cats.out", "w", stdout);
memset(h, -1, sizeof h);
cin >> n >> k;
for (int i = 1; i <= k; i++) cin >> x[i];
for (int i = 1; i <= k; i++) cin >> 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;
for (int i = 0; i < path.size(); i++)
cout << path[i] << " ";
return 0;
}