BZOJ2657: [Zjoi2012]旅游(journey)

我记得第一次看到这个题的时候我的小学弟把我们虐爆了
后来发现这TM就是树的直径啊!!!
日吗。。。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<map>
using namespace std;
#define Side side
struct side
{
    int x,y;
    inline friend bool operator <(Side a,Side b)
    {
        return min(a.x,a.y)<min(b.x,b.y)||(min(a.x,a.y)==min(b.x,b.y)&&max(a.x,a.y)<max(b.x,b.y));
    }
};
map<side,int>Q;
int f[2100001];
int g[2100001];
char c;
inline void read(int &a)
{
    a=0;do c=getchar();while(c<'0'||c>'9');
    while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();
}
struct Chain
{
    Chain *next; 
    int u;
    Chain(){next=NULL;}
}*Head[2000001];
inline void addside(int a,int b)
{Chain *tp=new Chain;tp->next=Head[a];Head[a]=tp;tp->u=b;}
int tot;

void DFS(int u,int fa)
{
    int max=0,sec=0;
    for(Chain*tp=Head[u];tp;tp=tp->next)
      if(tp->u!=fa)
        {
            DFS(tp->u,u);
            if(f[tp->u]>max)
               sec=max,max=f[tp->u];
            else if(f[tp->u]>sec)sec=f[tp->u];
        }
   f[u]=max+1;
   g[u]=sec+1+max;
}

int main()
{
    int n;
   scanf("%d",&n);  
    n-=2;
    Side tp;
    int a,b,c;
    for(int i=1;i<=n;i++)
    {
        ++tot;
        read(a),read(b),read(c);
        tp.x=a,tp.y=b;
        if(Q[tp])
          addside(Q[tp],tot),
          addside(tot,Q[tp]);
       else
         Q[tp]=tot;

        tp.y=c;
        if(Q[tp])
          addside(Q[tp],tot),
          addside(tot,Q[tp]);
       else
         Q[tp]=tot;

        tp.x=b;
        if(Q[tp])
          addside(Q[tp],tot),
          addside(tot,Q[tp]);
       else
         Q[tp]=tot;

    }   

   DFS(1,1);
   int ans=-1;
    for(int i=1;i<=tot;i++)
       ans=max(ans,f[i]),ans=max(ans,g[i]);
    printf("%d\n",ans);
   return 0;
}


你可能感兴趣的:(BZOJ2657: [Zjoi2012]旅游(journey))