Bzoj2657 [Zjoi2012]旅游(journey)
2017-02-25 13:45
381 查看
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
61 2 4
2 3 4
1 4 5
1 5 6
Sample Output
4HINT
4<=N<=200000
Source
树 最长路
在凸多边形的两个顶点之间连一条线,问如何连可以使得这条线穿过的三角形最多。
把每个三角形当作一个节点,在有共同边的两个三角形之间连长度为1的边,最后发现形成一个树结构,那么求树上最长链就可以了。
↑凸多边形的性质使得这么做是正确的。
↑什么性质?不可描述。怎么证明?画几个图,“显然可知”
做这题最逗的是,测试的时候过了,交一发bzoj发现WA了。WTF?提交之前压缩了下代码长度,就把71行求端点语句的括号缩没了,还傻傻没发现,蛤蛤蛤蛤蛤。
/*by SilverN*/ #include<algorithm> #include<iostream> #include<cstring> #include<cstdio> #include<cmath> #include<vector> #include<map> using namespace std; const int mxn=300010; int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } struct edge{ int v,nxt; }e[mxn<<1]; int hd[mxn],mct=0; void add_edge(int u,int v){ e[++mct].v=v;e[mct].nxt=hd[u];hd[u]=mct; e[++mct].v=u;e[mct].nxt=hd[v];hd[v]=mct; return; } struct tri{ int c[4]; }a[mxn]; int n,cnt=0; map<pair<int,int>,int>mp; void extend(tri x){ ++cnt; if(mp[make_pair(x.c[1],x.c[2])]){ add_edge(cnt,mp[make_pair(x.c[1],x.c[2])]); } else mp[make_pair(x.c[1],x.c[2])]=cnt; if(mp[make_pair(x.c[2],x.c[3])]){ add_edge(cnt,mp[make_pair(x.c[2],x.c[3])]); } else mp[make_pair(x.c[2],x.c[3])]=cnt; if(mp[make_pair(x.c[1],x.c[3])]){ add_edge(cnt,mp[make_pair(x.c[1],x.c[3])]); } else mp[make_pair(x.c[1],x.c[3])]=cnt; return; } int dis[mxn]; void DFS(int u,int fa){ dis[u]=dis[fa]+1; for(int i=hd[u];i;i=e[i].nxt){ int v=e[i].v; if(v==fa)continue; DFS(v,u); } return; } int main(){ // freopen("journey.in","r",stdin); // freopen("journey.out","w",stdout); int i,j; n=read();int ed=n-2; for(i=1;i<=ed;i++){ a[i].c[1]=read();a[i].c[2]=read();a[i].c[3]=read(); sort(a[i].c+1,a[i].c+4); extend(a[i]); } DFS(1,0); int ans=0,pos=1; for(i=1;i<=cnt;i++)if(dis[i]>ans){ans=dis[i];pos=i;}; DFS(pos,0); for(i=1;i<=cnt;i++) if(dis[i]>ans){ans=dis[i];} printf("%d\n",ans); return 0; }
相关文章推荐
- [BZOJ 2657][Zjoi2012]旅游(journey):树的直径
- [bzoj 2657] [Zjoi2012]旅游(journey)
- BZOJ 2657 [Zjoi2012]旅游(journey)
- BZOJ 2657: [Zjoi2012]旅游(journey)
- BZOJ2657: [Zjoi2012]旅游(journey)
- 【BZOJ 2657】 [Zjoi2012]旅游(journey)
- [BZOJ2657][Zjoi2012]旅游(journey)(dfs||树形dp)
- bzoj 2657: [Zjoi2012]旅游(journey) (map建图+树的直径)
- 【BZOJ】2657: [Zjoi2012]旅游(journey)
- bzoj2657: [Zjoi2012]旅游(journey)
- BZOJ 2657 ZJOI 2012 旅游(journey) 树的直径
- 【ZJOI2012】【BZOJ2657】旅游(journey)
- BZOJ 2657 [Zjoi2012] 旅游(journey)
- [bzoj2657][Zjoi2012]旅游 journey_ 对偶图_树形dp
- [BZOJ2657][Zjoi2012]旅游(journey)(一些特殊的技巧+树的直径)
- BZOJ 2657 ZJOI2012 旅游(journey) 树形DP
- BZOJ 2657 (ZJOI 2012 旅游) 求树上最长链(树的直径) MAP建树+BFS/DFS
- BZOJ2657:[ZJOI2012]旅游——题解
- 【ZJOI2012】bzoj2657 旅游
- [bzoj] 2657 ZJOI2012 旅游 || bfs