BZOJ2657 [Zjoi2012]旅游(journey) 【树的直径】
题目
到了难得的暑假,为了庆祝小白在数学考试中取得的优异成绩,小蓝决定带小白出去旅游~~
经过一番抉择,两人决定将T国作为他们的目的地。T国的国土可以用一个凸N边形来表示,N个顶点表示N个入境/出境口。T国包含N-2个城市,每个城市都是顶点均为N边形顶点的三角形(换而言之,城市组成了关于T国的一个三角剖分)。两人的旅游路线可以看做是连接N个顶点中不相邻两点的线段。
为了能够买到最好的纪念品,小白希望旅游路线上经过的城市尽量多。作为小蓝的好友,你能帮帮小蓝吗?
输入格式
每个输入文件中仅包含一个测试数据。
第一行包含两个由空格隔开的正整数N,N的含义如题目所述。
接下来有N-2行,每行包含三个整数 p,q,r,表示该城市三角形的三个顶点的编号(T国的N个顶点按顺时间方向从1至n编号)。
输出格式
输出文件共包含1行,表示最多经过的城市数目。(一个城市被当做经过当且仅当其与线路有至少两个公共点)
输入样例
6
1 2 4
2 3 4
1 4 5
1 5 6
输出样例
4
提示
4<=N<=200000
题解
题意:找一条对角线使经过尽量多的三角形
平面图联想到对偶图,发现对偶图是棵树,答案就是树的直径
建图时,将每个三角行的三条边放在一起排序,相同的边最多有两个,且这两个就是相邻的三角形
#include<iostream>
#include<cstdio>
#include<cmath>
#include<map>
#include<cstring>
#include<algorithm>
#define LL long long int
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define BUG(s,n) for (int i = 1; i <= (n); i++) cout<<s[i]<<' '; puts("");
using namespace std;
const int maxn = 200005,maxm = 100005,INF = 1000000000;
inline int read(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
return out * flag;
}
int h[maxn],ne = 2;
struct EDGE{int to,nxt;}ed[maxn << 1];
inline void build(int u,int v){
ed[ne] = (EDGE){v,h[u]}; h[u] = ne++;
ed[ne] = (EDGE){u,h[v]}; h[v] = ne++;
}
struct line{
int a,b,id;
}e[maxn * 3];
inline bool operator < (const line& a,const line& b){
return a.a == b.a ? a.b < b.b : a.a < b.a;
}
int n,m,vis[maxn],d[maxn],q[maxn];
void order(int& a,int& b,int& c){
if (a > b) swap(a,b);
if (a > c) swap(a,c);
if (b > c) swap(b,c);
}
int head,tail;
void solve(){
q[head = tail = 1] = 1;
int u,rt = 1; vis[1] = true;
while (head <= tail){
u = q[head++];
if (d[u] > d[rt]) rt = u;
Redge(u) if (!vis[to = ed[k].to]){
d[to] = d[u] + 1; vis[to] = true;
q[++tail] = to;
}
}
memset(d,0,sizeof(d));
memset(vis,0,sizeof(vis));
q[head = tail = 1] = rt; d[rt] = 1; vis[rt] = true;
while (head <= tail){
u = q[head++];
if (d[u] > d[rt]) rt = u;
Redge(u) if (!vis[to = ed[k].to]){
d[to] = d[u] + 1; vis[to] = true;
q[++tail] = to;
}
}
printf("%d\n",d[rt]);
}
int main(){
n = read();
int a,b,c;
REP(i,n - 2){
a = read(); b = read(); c = read();
order(a,b,c);
e[++m] = (line){a,b,i};
e[++m] = (line){b,c,i};
e[++m] = (line){a,c,i};
}
sort(e + 1,e + 1 + m);
for (int i = 1; i <= m; i++){
if (e[i].a == e[i - 1].a && e[i].b == e[i - 1].b)
build(e[i].id,e[i - 1].id);
}
solve();
return 0;
}
BZOJ2657 [Zjoi2012]旅游(journey) 【树的直径】的更多相关文章
- [ZJOI2012]旅游(树的直径)
[ZJOI2012]旅游 题目描述 到了难得的暑假,为了庆祝小白在数学考试中取得的优异成绩,小蓝决定带小白出去旅游~~ 经过一番抉择,两人决定将T国作为他们的目的地.T国的国土可以用一个凸N边形来表示 ...
- bzoj2657: [Zjoi2012]旅游(journey)
求树的直径 真是太神辣 #include<cstdio> #include<cstring> #include<cstdlib> #include<algor ...
- BZOJ2657: [Zjoi2012]旅游(journey) (树形DP)
题意:一个三角划分的凸多边形 画一条对角线 穿过最多的三角形 题解:把每一个三角形看作一个点 如果某条边是两个三角形的公共边 那么就把这两个三角形连边 然后问题就转化为求树上的最长链了 就当求个直径就 ...
- [ZJOI2012]旅游 对偶图 树的直径
Code: // luogu-judger-enable-o2 #include<cstdio> #include<iostream> #include<algorith ...
- 【BZOJ】2657: [Zjoi2012]旅游(journey)(树的直径)
题目 传送门:QWQ 分析 在任意两个不相邻的点连一条线,求这条线能穿过几个三角形. 建图比较讲究(详见代码) 求树的直径. 代码 #include <bits/stdc++.h> usi ...
- [bzoj2657][Zjoi2012]旅游 journey_ 对偶图_树形dp
旅游 bzoj-2657 Zjoi-2012 题目大意:题目链接 注释:$1\le K\le 2\cdot 10^5$. 想法:这题... 感觉和上一个题的提示有些类似,就是题目生怕你不知道这是一道对 ...
- P2610 [ZJOI2012]旅游 树的直径
这个题就是建图不太好建,但是我们一想,三角形貌似只能两两挨着,最后会变成一个二叉树,所以问题就变成求树的直径.建图用pair套map超级简单. 题干: 到了难得的暑假,为了庆祝小白在数学考试中取得的优 ...
- VIJOS1476旅游规划[树形DP 树的直径]
描述 W市的交通规划出现了重大问题,市政府下决心在全市的各大交通路口安排交通疏导员来疏导密集的车流.但由于人员不足,W市市长决定只在最需要安排人员的路口安放人员.具体说来,W市的交通网络十分简单,它包 ...
- [洛谷P2610] [ZJOI2012]旅游
洛谷题目链接:[ZJOI2012]旅游 题目描述 到了难得的暑假,为了庆祝小白在数学考试中取得的优异成绩,小蓝决定带小白出去旅游~~ 经过一番抉择,两人决定将T国作为他们的目的地.T国的国土可以用一个 ...
随机推荐
- python_13_break
for i in range(5): print('-----------',i) for j in range(5): print(j) if j>2: break####结束当前循环
- python_62_装饰器5
import time def timer(func): #timer(test1) func=test1 def deco(*args,**kwargs): start_time=time.time ...
- opensuse 系统启动自动加载模块
在/etc/modules-load.d目录下面加入想要自动加载的模块,例如自动加载raw模块 创建raw.conf文件,在文件中写入raw. 重启系统就可以了. 手动加载模块方法: modprobe ...
- UVA1629 Cake slicing
题目传送门 直接暴力定义f[x1][y1][x2][y2]是使对角为\((x1, y1),(x2, y2)\)这个子矩形满足要求的最短切割线长度 因为转移顺序不好递推,采用记忆化搜索 #include ...
- axios获取后端数据
axios向后端请求数据时,一直获取不到数据, 后来改成这样写获取到了数据 不是一个this,有人说用箭头函数就可以了.
- vue axios 攻略
Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中. 特点: 从浏览器中创建 XMLHttpRequest 从 node.js 发出 http 请求 支持 ...
- 谈谈Integer中的静态类IntegerCache
学习的本质就是一个赋值的过程,用新知识来覆盖你的旧知识或者无知(null).掌握知识是自己的, 分享知识,才能帮助更多的人,创造更大的价值.学贵以恒,以此自勉,与君共享.----曦阳X ...
- restful api 规范
- https://www.atlassian.com
https://www.atlassian.com 解决:confluence 5.9.4 一次性恢复30个插件 - 简书 https://www.jianshu.com/p/c32d8aa739b8 ...
- MySQL批量插入大量数据方法
在MySQL数据库中,如果要插入上百万级的记录,用普通的insert into来操作非常不现实,速度慢人力成本高,推荐使用Load Data或存储过程来导入数据,我总结了一些方法分享如下,主要基于My ...