BZOJ-2657: [Zjoi2012]旅游(journey) (树形DP求最长链)

Posted 可惜没如果=_=

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ-2657: [Zjoi2012]旅游(journey) (树形DP求最长链)相关的知识,希望对你有一定的参考价值。

2657: [Zjoi2012]旅游(journey)

Time Limit: 5 Sec  Memory Limit: 128 MB
Submit: 1037  Solved: 655
[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

两个相邻的三角形之间连边,然后求可以发现这是一棵树,求其中的最长链即可

最长链的求法值得学习,f[x]表示以x为根向下的最长链,g[x]表示以x为根向下的次长链 那么以x为最上面的点的最长链的长度就为f[x]+g[x]+1;

竟然数组开小了RE了一次 _(:зゝ∠)_ 论laj的AC率为什么还是很低 _(:зゝ∠)_

 1 #include "bits/stdc++.h"
 2 using namespace std;
 3 typedef long long LL;
 4 const int MAX=2e5+5;
 5 int n,f[MAX],g[MAX],ans;
 6 int tot,head[MAX],adj[MAX<<1],next[MAX<<1];
 7 struct Node{int x,y,id;}p[MAX<<2];int tx;
 8 bool cmp(Node x,Node y){return x.x==y.x?x.y<y.y:x.x<y.x;}
 9 inline int read(){
10     int an=0,x=1;char c=getchar();
11     while (c<0 || c>9) {if (c==-) x=-1;c=getchar();}
12     while (c>=0 && c<=9) {an=(an<<3)+(an<<1)+c-0;c=getchar();}
13     return an*x;
14 }
15 void addedge(int u,int v){
16     tot++;adj[tot]=v,next[tot]=head[u],head[u]=tot;
17 }
18 void dfs(int x,int fa){
19     int i,j;
20     for (i=head[x];i;i=next[i]){
21         if (adj[i]==fa) continue;
22         dfs(adj[i],x);
23         if (f[x]<f[adj[i]]+1){
24             g[x]=f[x];
25             f[x]=f[adj[i]]+1;
26         }
27         else g[x]=max(g[x],f[adj[i]]+1);
28     }
29     ans=max(ans,f[x]+g[x]);
30 }
31 int main(){
32     freopen ("journey.in","r",stdin);freopen ("journey.out","w",stdout);
33     int i,j,x,y,z;
34     n=read();tot=1;
35     for (i=1;i<=n-2;i++){
36         x=read(),y=read(),z=read();
37         if (x>y) swap(x,y); if (y>z) swap(y,z); if (x>y) swap(x,y);
38         p[++tx].x=x,p[tx].y=y,p[tx].id=i;
39         p[++tx].x=x,p[tx].y=z,p[tx].id=i;
40         p[++tx].x=y,p[tx].y=z,p[tx].id=i;
41     }
42     sort(p+1,p+tx+1,cmp);
43     for (i=1;i<=tx;i++)
44         if (p[i].x==p[i-1].x && p[i].y==p[i-1].y) addedge(p[i].id,p[i-1].id),addedge(p[i-1].id,p[i].id);
45     dfs(1,0);
46     printf("%d",ans+1);
47     return 0;
48 }

 

以上是关于BZOJ-2657: [Zjoi2012]旅游(journey) (树形DP求最长链)的主要内容,如果未能解决你的问题,请参考以下文章

ZJOI2007棋盘制作[动规 悬线法]

BZOJ4456 [Zjoi2016]旅行者 / UOJ #184 ZJOI2016旅行者

[ZJOI2008]生日聚会

BZOJ3527: [Zjoi2014]力

[ZJOI2006]物流运输

[ZJOI2014]力