zoukankan      html  css  js  c++  java
  • Bzoj2657 [Zjoi2012]旅游(journey)

    Time Limit: 5 Sec  Memory Limit: 128 MB
    Submit: 924  Solved: 585
    [Submit][Status][Discuss]

    Description

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

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

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

    Input

     每个输入文件中仅包含一个测试数据。
    第一行包含两个由空格隔开的正整数N,N的含义如题目所述。
         接下来有N-2行,每行包含三个整数 p,q,r,表示该城市三角形的三个顶点的编号(T国的N个顶点按顺时间方向从1至n编号)。

    Output

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

    Sample Input

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

    Sample Output

    4

    HINT

    4<=N<=200000

    Source

    树 最长路

    凸多边形的两个顶点之间连一条线,问如何连可以使得这条线穿过的三角形最多。

    把每个三角形当作一个节点,在有共同边的两个三角形之间连长度为1的边,最后发现形成一个树结构,那么求树上最长链就可以了。

    ↑凸多边形的性质使得这么做是正确的。

    ↑什么性质?不可描述。怎么证明?画几个图,“显然可知”

    做这题最逗的是,测试的时候过了,交一发bzoj发现WA了。WTF?提交之前压缩了下代码长度,就把71行求端点语句的括号缩没了,还傻傻没发现,蛤蛤蛤蛤蛤。

     1 /*by SilverN*/
     2 #include<algorithm>
     3 #include<iostream>
     4 #include<cstring>
     5 #include<cstdio>
     6 #include<cmath>
     7 #include<vector>
     8 #include<map>
     9 using namespace std;
    10 const int mxn=300010;
    11 int read(){
    12     int x=0,f=1;char ch=getchar();
    13     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    14     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
    15     return x*f;
    16 }
    17 struct edge{
    18     int v,nxt;
    19 }e[mxn<<1];
    20 int hd[mxn],mct=0;
    21 void add_edge(int u,int v){
    22     e[++mct].v=v;e[mct].nxt=hd[u];hd[u]=mct;
    23     e[++mct].v=u;e[mct].nxt=hd[v];hd[v]=mct;
    24     return;
    25 }
    26 struct tri{
    27     int c[4];
    28 }a[mxn];
    29 int n,cnt=0;
    30 map<pair<int,int>,int>mp;
    31 void extend(tri x){
    32     ++cnt;
    33     if(mp[make_pair(x.c[1],x.c[2])]){
    34         add_edge(cnt,mp[make_pair(x.c[1],x.c[2])]);
    35     }
    36     else mp[make_pair(x.c[1],x.c[2])]=cnt;
    37     
    38     if(mp[make_pair(x.c[2],x.c[3])]){
    39         add_edge(cnt,mp[make_pair(x.c[2],x.c[3])]);
    40     }
    41     else mp[make_pair(x.c[2],x.c[3])]=cnt;
    42     
    43     if(mp[make_pair(x.c[1],x.c[3])]){
    44         add_edge(cnt,mp[make_pair(x.c[1],x.c[3])]);
    45     }
    46     else mp[make_pair(x.c[1],x.c[3])]=cnt;
    47     return;
    48 }
    49 int dis[mxn];
    50 void DFS(int u,int fa){
    51     dis[u]=dis[fa]+1;
    52     for(int i=hd[u];i;i=e[i].nxt){
    53         int v=e[i].v;
    54         if(v==fa)continue;
    55         DFS(v,u);
    56     }
    57     return;
    58 }
    59 int main(){
    60 //    freopen("journey.in","r",stdin);
    61 //    freopen("journey.out","w",stdout);
    62     int i,j;
    63     n=read();int ed=n-2;
    64     for(i=1;i<=ed;i++){
    65         a[i].c[1]=read();a[i].c[2]=read();a[i].c[3]=read();
    66         sort(a[i].c+1,a[i].c+4);
    67         extend(a[i]);
    68     }
    69     DFS(1,0);
    70     int ans=0,pos=1;
    71     for(i=1;i<=cnt;i++)if(dis[i]>ans){ans=dis[i];pos=i;};
    72     DFS(pos,0);
    73     for(i=1;i<=cnt;i++)    if(dis[i]>ans){ans=dis[i];}
    74     printf("%d
    ",ans);
    75     return 0;
    76 }
  • 相关阅读:
    Go语言趣学指南lesson3
    简单的>this
    多媒体查询
    解析对象原型链
    笑对人生,坐看云起云落
    HTML5
    javascript函数及作用域的小结
    不得不知call()和apply()
    浅谈弹性盒子布局
    编译原理实验(算符优先文法)
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6441645.html
Copyright © 2011-2022 走看看