zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    python3 bytes数据类型探讨
    字典
    列表及元组
    在py文件中设置文件头
    函数的作用域、global与nonlocal
    python中 的意义及用法
    int、bool和str
    while循环、格式化输出、运算符和编码初识
    python初认识、基础数据类型以及 if 流程控制
    列表遍历和生成器遍历效率对比
  • 原文地址:https://www.cnblogs.com/victorique/p/8426770.html
Copyright © 2011-2022 走看看