广东工业大学程序设计竞赛决赛 tmk找三角

今天是校赛的日子,为了庆祝这么喜庆的日子,TMK打算买些礼物给女票LSH庆祝一下。
提供了一个算法,判边集S,O(|S|)找能存在构成三角形的3条边(用了priority_queue,jp提供)
提供了找树中节点路劲的方法O(h),就是找公共祖先,深度深的往上
用map数组做到了即时访问边值O(logn)(虽然后来觉得可以存在节点上,改用vector+pair,优化成O(1)),并利用node.d做访问标记,同时利用map[vi]迭代器来遍历(vi,vw)

#include<algorithm>
#include<set>
#include<cstring>
#include<map>
#include<cstdio>
#include<queue>
using namespace std;
const int mN=100000+5000;//father
map<int ,int > vi[mN];
struct Node{
	int d;
	int f;
};
Node T[mN];
int cntT;
priority_queue<int > lens;
const int root=1;
int Node[mN];
void inp();//输入
void bui(int ,int,int );//建树
void tbui();//测试建树
const char ans[][10]={
	"No\n",
	"Yes\n"
};
int n;
int que(int ,int );//查找两节点间初级路劲,并加入lens
void dea();//处理边集lens
int main(){
	int Tcase,q;
	int a,b;
	scanf("%d", &Tcase);
	while(Tcase--){
		memset(T,0,sizeof(T));
	//	cntT=0;
		inp();
//		printf("%d %d",Tcase, n);
		bui(1,1,1);
		//tbui();
		scanf("%d",&q);
		while(q--){
			while(!lens.empty()){
				lens.pop();
			}
			scanf("%d%d", &a,&b);
			que(a,b);
			//printf("%d %d -> %d \n",a,b,que(a,b));
			dea();
		}
	}
//	printf("%d",Tcase);
}
void dea(){
	if(lens.size()<3){
		printf("%s",ans[0]);
		return ;
	}
	int a,b,c;
	while(lens.size()>=3){
		a=lens.top();lens.pop();
		b=lens.top();lens.pop();
		c=lens.top();lens.pop();
		if(b+c>a){
			printf("%s",ans[1]);
			return ;
		}
		lens.push(b),lens.push(c);
	}
	printf("%s",ans[0]);
}
int que(int a,int b){
	while(a!=b){
		if(T[a].d>T[b].d){
			lens.push(vi[a][T[a].f]);
			a=T[a].f;
		}
		else {
			lens.push(vi[b][T[b].f]);
			b=T[b].f;
		}
	}
	return a;
}
void tbui(){
	for(int i =1;i<=n;i++){
		printf("%d :%d %d \n ",i,T[i].d,T[i].f);
	}
}
void bui(int d,int f,int cur){
	T[cur].d=d;
	T[cur].f=f;
	for(auto it =vi[cur].begin();it!=vi[cur].end();it++){
		if(T[it->first].d)continue;
//		printf("%d:  %d\n",cur,it->first);
		bui(d+1,cur,it->first);
	}
}
void inp(){
	int a,b,c;
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		vi[i].clear();
	}
	for(int i = 0; i< n-1;i++){
		scanf("%d%d%d",&a,&b,&c);
		vi[a][b]=c;
		vi[b][a]=c;
	}
//	for(int i=1;i<=n;i++){
//		for(auto it =vi[i].begin();it!=vi[i].end();it++){
//			printf("%d :%d %d\n",i,it->first,it->second);
//		}
//	}
}
posted @ 2017-03-28 20:35  xsthunder  阅读(251)  评论(0)    收藏  举报