QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#805031#9570. Binary TreeKogenta2010TL 2ms6696kbC++143.2kb2024-12-08 12:03:072024-12-08 12:03:07

Judging History

你现在查看的是最新测评结果

  • [2024-12-08 12:03:07]
  • 评测
  • 测评结果:TL
  • 用时:2ms
  • 内存:6696kb
  • [2024-12-08 12:03:07]
  • 提交

answer

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
bool mark[maxn],p[maxn];
struct edge{
	int to;
	int block_size;
	edge(int to_=0,int sz_=0):to(to_),block_size(sz_){}
	bool const operator <(const edge &b){
		if(mark[to]){
			if(mark[b.to])return 0;
			else return 1;
		}
		else if(mark[b.to])return 0;
		else return block_size<b.block_size;
	}
};
vector<edge>v[maxn];
int edge_cnt[maxn];
void build_edge(int x,int y){
	if(x==0||y==0||x==y)return ;
	if(v[x].size()<=edge_cnt[x]){
		v[x].push_back((edge){y,0});
		edge_cnt[x]++;
	}
	else{
		v[x][edge_cnt[x]].to=y;
		v[x][edge_cnt[x]++].block_size=0;
	}
	if(v[y].size()<=edge_cnt[y]){
		v[y].push_back((edge){x,0});
		edge_cnt[y]++;
	}
	else{
		v[y][edge_cnt[y]].to=x;
		v[y][edge_cnt[y]++].block_size=0;
	}
	return ;
}
edge fa[maxn];
stack<int>RemainNode;
queue<int>SelectNode;
void dfs(int x,int prev,int EdgeID){
	if(mark[x])return ;
	//cout<<"Now Goes to "<<x<<" (Prev:"<<prev<<","<<EdgeID<<")"<<endl;
	//system("pause");
	fa[x].to=prev;
	RemainNode.push(x);
	if(x!=prev){
		v[prev][EdgeID].block_size=1;
	}
	for(int i=0;i<edge_cnt[x];i++){
		if(v[x][i].to==prev){
			fa[x].block_size=i;
			continue;
		}
		dfs(v[x][i].to,x,i);
		if(x!=prev)v[prev][EdgeID].block_size+=v[x][i].block_size;
	}
}
struct cmp_for_block{
	bool operator()(const int &a,const int &b){
		return v[a][edge_cnt[a]-1].block_size>v[b][edge_cnt[b]-1].block_size;
	}
};
priority_queue<int,vector<int>,cmp_for_block>blocks;
int main(){
	int t;
	cin>>t;
	while(t--){
		//cout<<"Remain "<<t<<" Group(s)"<<endl;
		int n,x,y;
		cin>>n;
		for(int i=1;i<=n;i++){
			edge_cnt[i]=0;
			mark[i]=0;
			p[i]=0;
		}
		for(int i=1;i<=n;i++){
			cin>>x>>y;
			build_edge(x,i);
			build_edge(y,i);
			p[x]=p[y]=1;
		}
		int rt=0;
		for(int i=1;i<=n;i++){
			if(!p[i]){
				rt=i;
				break;
			}
		}
		while(1){
			dfs(rt,rt,-1);
			int sz=RemainNode.size();
			if(sz==1){
				break;
			}
			int now;
			while(!RemainNode.empty()){
				now=RemainNode.top();
				RemainNode.pop();
				if(!RemainNode.empty())v[now][fa[now].block_size].block_size=sz-1;
				for(int i=0;i<edge_cnt[now];i++){
					if(i==fa[now].block_size)continue;
					if(!RemainNode.empty())v[now][fa[now].block_size].block_size-=v[now][i].block_size;
				}
				sort(v[now].begin(),v[now].begin()+edge_cnt[now]);
				blocks.push(now);
			}
			now=blocks.top();
			//cout<<"Found Center: "<<now<<endl;
			while(!blocks.empty()){
				blocks.pop();
			}
			for(int i=edge_cnt[now]-1;i>=0;i--){
				if(mark[v[now][i].to])break;
				SelectNode.push(v[now][i].to);
				if(SelectNode.size()==2)break;
			}
			int ask1=SelectNode.front(),ask2,ans;
			SelectNode.pop();
			if(SelectNode.empty()){
				ask2=now;
			}
			else{
				ask2=SelectNode.front();
				SelectNode.pop();
			}
			cout<<"? "<<ask1<<' '<<ask2<<endl;
			cin>>ans;
			if(ans==1){
				mark[ask1]=mark[ask2]=1;
				rt=now;
			}
			else{
				if(ans==0){
					mark[now]=1;
					rt=ask1;
				}
				else if(ans==2){
					if(ask2==now){
						mark[ask1]=1;
						rt=now;
					}
					else{
						mark[now]=1;
						rt=ask2;
					}
				}
			}
		}
		cout<<"! "<<rt<<endl;
	}
	return 0;
}

詳細信息

Test #1:

score: 100
Accepted
time: 2ms
memory: 6696kb

input:

2
5
0 0
1 5
2 4
0 0
0 0
1
0
2
0 2
0 0
2

output:

? 3 5
? 2 1
! 2
? 1 2
! 2

result:

ok OK (2 test cases)

Test #2:

score: -100
Time Limit Exceeded

input:

5555
8
2 0
8 6
0 0
3 0
0 0
7 0
0 0
5 4
0
0
2
8
0 0
1 4
2 0
0 0
7 8
0 0
3 0
6 0
0
1
0
8
5 8
0 0
1 7
0 0
0 0
4 2
0 0
6 0
0
1
2
5
4 5
3 1
0 0
0 0
0 0
0
2
8
0 0
0 0
5 6
0 0
1 4
2 0
3 8
0 0
1
0
5
3 0
5 1
0 0
0 0
4 0
0
2
5
5 0
0 0
0 0
3 0
2 4
0
0
3
3 0
1 0
0 0

output:

? 2 4
? 2 7
? 2 1
! 1
? 3 5
? 3 4
? 2 1
! 2
? 8 3
? 8 2
? 6 4
! 4
? 2 5
? 2 3
! 3
? 7 5
? 3 2
! 3
? 5 1
? 5 4
! 4
? 4 1
? 4 3
! 4
? 3 4

result: