P2610 【[ZJOI2012]旅游】(dfs+树的直径)

楼下那篇题解说实话就是什么都没说,所以我再发一篇正常一点的。

楼下思路大体是正确的,但是之所以是说什么都没说,是因为他有两个比较致命的遗漏。首先是点,这里的点不是平时我们认为的点,如果多少接触过对偶图很容易看出来,这个题实际上要把每个三角形当作点,而把有临边的三角形连边,这样我们就可以大体上得到一棵树,至于怎么连这个边,使用map和pair进行操作,具体说来很麻烦,可以上网某度以下。

建完图了之后,不难看出,我们要的结果就是建出来的这个树的最长链,然后就是找到一个最长链的端点的问题。由于这是一棵树,所以我们可以通过dfs或bfs求出其中的一个端点,然后从这个端点再来一次,求出的最大深度就是我们要的答案。由于这个题的数据限制,所以虽然这么建完图之后spfa绝对不慢,可是还是会T2~3个点,虽然你想A掉可以开O2优化,但是还是希望用搜索搜索出来。还有一个,不要cin,这个必T无疑,除非你开O2.。。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<iomanip>
#include<map>
#define re register
#define ll long long
using namespace std;
struct po
{
    int nxt,to,dis;
};
map<pair<int,int>,int> m;
po edge[4000001];
int q[1000001],head[1000001],dis[300001],b[300001],temp[400001][3];
int n,s,t,r,st,to,ans,maxx,num;
inline int read()
{
    int x=0,c=1;
    char ch=' ';
    while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    while(ch=='-')c*=-1,ch=getchar();
    while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    return x*c;
}
inline void add_edge(int from,int to,int dis)
{
    edge[++num].nxt=head[from];
    edge[num].to=to;
    edge[num].dis=dis;
    head[from]=num;
}
inline void finish(int id,int x,int y)
{
    int s=m[make_pair(x,y)];
    if(s)
    {
        add_edge(s,id,1);
        add_edge(id,s,1);
        m.erase(m.find(make_pair(x,y)));
    }else
    m[make_pair(x,y)]=id;
}
inline void spfa(int x)
{
    memset(dis,127,sizeof(dis));
    memset(b,0,sizeof(b));
    int front=0,tail=1;
    dis[x]=0;
    q[tail]=x;
    b[x]=1;
    while(front<tail)
    {
        int now=q[++front];
        b[now]=0;
        for(re int i=head[now];i;i=edge[i].nxt)
        {
            int u=edge[i].to;
            if(dis[u]>edge[i].dis+dis[now])
            {
                dis[u]=edge[i].dis+dis[now];
                if(!b[u])
                {
                    b[u]=1;
                    q[++tail]=u;
                }
            }
        }
    }
}
inline void bfs(int x)
{
    memset(b,0,sizeof(b));
    int front=0,tail=1;
    temp[tail][1]=x;
    temp[tail][2]=1;
    b[x]=1;
    while(front<tail)
    {
        int now=temp[++front][1];
        int dep=temp[front][2];
        if(dep>maxx)
        {
            st=now;
            maxx=dep;
        }
        for(re int i=head[now];i;i=edge[i].nxt)
        {
            int u=edge[i].to;
            if(!b[u])
            {
                b[u]=1;
                temp[++tail][1]=u;
                temp[tail][2]=dep+1;
            }
        }
    }
}
int main()
{
    n=read();
    for(re int i=1;i<=n-2;i++)
    {
        s=read();t=read();r=read();
        if(s>t)
        swap(s,t);
        if(s>r)
        swap(s,r);
        if(t>r)
        swap(t,r);
        finish(i,s,t);
        finish(i,s,r);
        finish(i,t,r);
    }

    bfs(1);
    maxx=0;
    bfs(st);
    cout<<maxx;
}
原文地址:https://www.cnblogs.com/victorique/p/8426770.html