天天看点

省选专练ZJOI2012旅游

STL在开O2后自然是大水题。

考点:树的直径。

第一二次构图。

把每一个三角块相邻的建边。

怎么建?STL-你都做到这个题了MAP hash两个值铁定会吧。

但是ZJOI没有那么好心,不过你也有70分了。

于是这样:把两点建边。排个序。

相同的时候连起来。

树的直径。

很多人求复杂了。

树的直径一遍DFS就可以,不需要两遍BFS。

#include<bits/stdc++.h>
using namespace std;
const int N= 500000;
struct Triangle{
	int p,q,r;
}a[N];
map<pair<int,int>,int > hash;
int n;
struct Node{
	int u,v,nxt;
}e[N*4];
int cnt=0;
int first[N]={0};
void add(int u,int v){
	cnt++;
	e[cnt].u=u;
	e[cnt].v=v;
	e[cnt].nxt=first[u];
	first[u]=cnt;
}
//
queue<int> q;
int dis[N]={0};
int rd[N]={0};
void SPFA(){
	while(!q.empty()){
		int x=q.front();
		q.pop();
		for(int i=first[x];i;i=e[i].nxt){
			int v=e[i].v;
			if(rd[v]==0)
				continue;
			if(dis[v]<dis[x]+1){
				dis[v]=dis[x]+1;
			}
			rd[v]--;
			if(rd[v]==0){
				q.push(v);
			}
		}
	}
}
int ans=0;
int sum[N]={0};
void dfs(int u,int fat){
	sum[u]=1;
	for(int i=first[u];i;i=e[i].nxt){
		int v=e[i].v;
		if(v==fat)
			continue;
		dfs(v,u);
		ans=max(ans,sum[u]+sum[v]);
		sum[u]=max(sum[u],sum[v]+1);
	}
}
int main(){
	scanf("%d",&n);
	n-=2;
	for(int i=1;i<=n;i++){
		int p,q,r;
		scanf("%d%d%d",&p,&q,&r);
		pair<int,int> A;
		A.first=p;
		A.second=q;
		if(p>q){
			swap(A.first,A.second);
		}
		if(hash.count(A)){
			add(i,hash[A]);
			add(hash[A],i);
//			cout<<i<<" "<<hash[A]<<endl;
		}
		else{
			hash[A]=i;
		}
		A.first=q;
		A.second=r;
		if(q>r){
			swap(A.first,A.second);
		}
		if(hash.count(A)){
			add(i,hash[A]);
			add(hash[A],i);
//			cout<<i<<" "<<hash[A]<<endl;
		}
		else{
			hash[A]=i;
		}
		A.first=p;
		A.second=r;
		if(p>r){
			swap(A.first,A.second);
		}		
		if(hash.count(A)){
			add(i,hash[A]);
			add(hash[A],i);
//			cout<<i<<" "<<hash[A]<<endl;
		}
		else{
			hash[A]=i;
		}		
	}
//	cout<<cnt<<endl;
//	SPFA();
	dfs(1,0);
	cout<<ans<<endl; 
}