您的位置:首页 > 其它

[BZOJ 2657][Zjoi2012]旅游(journey):树的直径

2017-06-15 14:19 459 查看
点击这里查看原题

这道题应该把城市看成点,相邻的城市之间连边,这样会形成一棵树,答案即为树的直径。

/*
User:Small
Language:C++
Problem No.:2657
*/
#include<bits/stdc++.h>
#define ll long long
#define inf 999999999
using namespace std;
const int M=2e5+5,mod=5e6;
int n,tot,fir[M],dis[M];
struct edge{
int v,nex;
}e[M<<1];
void add(int u,int v){
e[++tot]=(edge){v,fir[u]};
fir[u]=tot;
}
struct Hash{
int fir[mod+5],tot,nex[M*3],v[M*3];
ll w[M*3];
void check(int a,int b,int x){
ll num=(ll)a*n+b;
int cc=num%mod;
for(int i=fir[cc];i;i=nex[i])
if(w[i]==num){
add(v[i],x);
add(x,v[i]);
return;
}
tot++;
nex[tot]=fir[cc];
w[tot]=num;
v[tot]=x;
fir[cc]=tot;
}
}h;
int bfs(int s){
memset(dis,127,sizeof(dis));
queue<int> q;
dis[s]=0;
q.push(s);
int res=0;
while(!q.empty()){
int u=q.front();
q.pop();
res=u;
for(int i=fir[u];i;i=e[i].nex){
int v=e[i].v;
if(dis[v]>dis[u]+1){
dis[v]=dis[u]+1;
q.push(v);
}
}
}
return res;
}
int main(){
freopen("data.in","r",stdin);//
scanf("%d",&n);
for(int i=1;i<=n-2;i++){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
if(b>c) swap(b,c);
if(a>c) swap(a,c);
if(a>b) swap(a,b);
h.check(a,b,i);
h.check(a,c,i);
h.check(b,c,i);
}
int u=bfs(1);
printf("%d\n",dis[bfs(u)]+1);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: