CF2001C 题解
Wuming_Shi · · 题解
CF2001C 题解
题意
交互题。有一颗
思路
函数 query(int a,int b) 表示处理点
可以设某个点为树根,每次询问树根与一个未被标记的点 。然后递归处理:
先把询问的
对于前者,直接递归下去即可。
对于后者,分类讨论一下:若
递归的终止条件为询问的点
最后输出这些边即可。
代码
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 2010;
int t, n;
typedef pair<int, int> PII;
vector<PII> ans;
bool vis[MAXN];
void query(int a, int b) {
vis[b] = 1;
cout << "? " << a << " " << b << endl;
cout.flush();
int mid; cin >> mid; //中点
if (mid == a) { //中点与a重合,递归终止
ans.push_back({a, b});
return;
}
if (!vis[mid]) query(a, mid); //处理a到中点的路径
query(mid, b); //处理中点到b的路径
}
void solve() {
cin >> n;
for (int i = 2; i <= n; i++) {
if (!vis[i]) { //选取未被标记的点
query(1, i);
}
}
cout << "! ";
for (PII i : ans) { //输出答案
cout << i.first << " " << i.second << " ";
}
cout << endl;
cout.flush();
}
void init() {
for (int i = 1; i <= n; i++) {
vis[i] = 0;
}
ans.clear();
}
int main() {
cin >> t;
while (t--) {
solve();
init();
}
return 0;
}