zoukankan      html  css  js  c++  java
  • [ZJOI2012] 旅游

    题目描述

    到了难得的暑假,为了庆祝小白在数学考试中取得的优异成绩,小蓝决定带小白出去旅游~~

    经过一番抉择,两人决定将T国作为他们的目的地。T国的国土可以用一个凸N边形来表示,N个顶点表示N个入境/出境口。T国包含N-2个城市,每个城市都是顶点均为N边形顶点的三角形(换而言之,[b]城市组成了关于T国的一个三角剖分[/b])。[b]两人的旅游路线可以看做是连接N个顶点中不相邻两点的线段[/b]。

    为了能够买到最好的纪念品,小白希望旅游路线上经过的城市尽量多。作为小蓝的好友,你能帮帮小蓝吗?

    输入输出格式

    输入格式:

    每个输入文件中仅包含一个测试数据。

    第一行包含两个由空格隔开的正整数N,N的含义如题目所述。

    接下来有N-2行,每行包含三个整数 p,q,r,表示该城市三角形的三个顶点的编号(T国的N个顶点按顺时间方向从1至n编号)。

    输出格式:

    输出文件共包含1行,表示最多经过的城市数目。([b]一个城市被当做经过当且仅当其与线路有至少两个公共点[/b])

    输入输出样例

    输入样例#1: 复制

    6
    1 2 4
    2 3 4
    1 4 5
    1 5 6

    输出样例#1: 复制

    4

    说明

    对于20%的数据, n<=2000
    对于100%的数据, 4<=n<=200000

    Solution

    一句话题意,三个边围成一个城市,拥有共同边的城市可以互相到达。
    显然,这个图可以建成一棵树,拥有共同城市的建边,用map存下,这条边有没有出现过,求树上最长路,树的直径,没了,一道水题。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<map>
    using namespace std;
    typedef pair<int,int> pr;
    map<pr,int> q;
    struct node
    {
        int to,next,w;
    }a[2001010];
    int len,last[501010],d[501000];
    void add(int a1,int a2,int a3)
    {
        a[++len].to=a2;
        a[len].w=a3;
        a[len].next=last[a1];
        last[a1]=len;
    }
    void dfs(int x,int father)
    {
        for(int i=last[x];i;i=a[i].next)
        {
            int to=a[i].to;
            if(to==father) continue;
            d[to]=d[x]+a[i].w;
            dfs(to,x);
        }
    }
    int main()
    {
        int n,x,y,z;
        cin>>n;
        for(int i=1;i<=n-2;i++)
        {
            scanf("%d%d%d",&x,&y,&z);
            if(x>y) swap(x,y);
            if(y>z) swap(y,z);
            if(x>y) swap(x,y);
            int s=q[pr(x,y)];
            if(s) add(i,s,1),add(s,i,1);
            else q[pr(x,y)]=i;
            s=q[pr(x,z)];
            if(s) add(i,s,1),add(s,i,1);
            else q[pr(x,z)]=i;
            s=q[pr(y,z)];
            if(s) add(i,s,1),add(s,i,1);
            else q[pr(y,z)]=i;
        }
        dfs(1,0);
        int l=0,r=0;
        for(int i=1;i<=n;i++) if(d[i]>d[l]) l=i;
        memset(d,0,sizeof(d));
        dfs(l,0);
        for(int i=1;i<=n;i++) if(d[i]>d[r]) r=i;
        cout<<d[r]+1<<endl;
    }
    

    博主蒟蒻,可以随意转载,但必须附上原文链接k-z-j

  • 相关阅读:
    React的状态管理工具
    Ant Design
    Mac 10.12安装专业抓包工具Wireshark
    Mac 10.12安装飞鸽传书IPMessager
    Mac 10.12安装XMind
    Mac 10.12安装SVN工具SmartSVM 7.6
    Mac 10.12安装Windows远程桌面工具Microsoft Remote Desktop
    Mac 10.12安装Office 2011
    Mac 10.12安装迅雷2.7.2
    Mac 10.12安装虚拟机软件VMware Fusion 12
  • 原文地址:https://www.cnblogs.com/kzj-pwq/p/9507643.html
Copyright © 2011-2022 走看看