版权声明:本文为DyingShu原创文章,转载请注明出处哦。 https://blog.csdn.net/DyingShu/article/details/82952182
这题神了。。。
题意:在凸多边形中,画一条两个不相邻顶点之间的线段,使经过的三角形个数最多。
题解:
对于两个有公共边的三角形,可以发现若有一条直线穿过某个三角形并从公共边出去,则一定会选中两个三角形(显然)。而如果直线穿过的是另外两条边,就会和另外两条边外面的三角形连在一起。
所以朝着有公共边的两个三角形连一条边。不难发现建出来的图是一棵树,而直线是不能分叉的,所以问题就转化为求这棵树的直径了。
有点蒙蔽,不过感觉好正确的样子
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN = 200001;
int fir[MAXN], nxt[MAXN << 1], to[MAXN << 1], cnt;
int Begin, End, dis[MAXN];
struct Triangle{
int x, y, z;
}Tri[MAXN];
struct E{
int a, b, num;
inline bool operator < (const E &e) const{
if(a == e.a) return b < e.b;
return a < e.a;
}
inline bool operator == (const E &e) const{
return (a == e.a && b == e.b);
}
}Edge[MAXN << 2];
int tot;
inline int read(){
int k = 0, f = 1; char ch = getchar();
while(ch < '0' || ch > '9'){if(ch == '-') f = -1; ch = getchar();}
while(ch >= '0' && ch <= '9'){k = k*10 + ch - '0'; ch = getchar();}
return k * f;
}
inline void add_edge(int a, int b){
to[cnt] = b;
nxt[cnt] = fir[a];
fir[a] = cnt++;
}
void dfs1(int u, int fa){
if(dis[u] > dis[Begin]) Begin = u;
for(int i = fir[u]; i != -1; i = nxt[i]){
int v = to[i];
if(v == fa) continue;
dis[v] = dis[u] + 1;
dfs1(v, u);
}
}
void dfs2(int u, int fa){
if(dis[u] > dis[End]) End = u;
for(int i = fir[u]; i != -1; i = nxt[i]){
int v = to[i];
if(v == fa) continue;
dis[v] = dis[u] + 1;
dfs2(v, u);
}
}
int main(){
freopen("in.txt", "r", stdin);
memset(fir, -1, sizeof(fir));
int n = read() - 2;
for(int i = 1; i <= n; i++){
int a = read(), b = read(), c = read();
if(a > c){
swap(a, c);
}
if(a > b){
swap(a, b);
}
if(b > c){
swap(b, c);
}
Tri[i].x = a, Tri[i].y = b, Tri[i].z = c;
Edge[++tot] = (E){a, b, i};
Edge[++tot] = (E){b, c, i};
Edge[++tot] = (E){a, c, i};
}
sort(Edge + 1, Edge + tot + 1);
// for(int i = 1; i <= tot; i++){
// printf("%d %d %d\n", Edge[i].a, Edge[i].b, Edge[i].num);
// }
for(int i = 1; i < tot; i++){
if(Edge[i] == Edge[i + 1]){
add_edge(Edge[i].num, Edge[i + 1].num);
add_edge(Edge[i + 1].num, Edge[i].num);
}
}
if(Edge[1] == Edge[n]){
add_edge(Edge[1].num, Edge[n].num);
add_edge(Edge[n].num, Edge[1].num);
}
// printf("cnt = %d\n", cnt);
int Ans = 0;
memset(dis, 0, sizeof(dis));
dfs1(1, 0);
memset(dis, 0, sizeof(dis));
// printf("Begin = %d\n", Begin);
dfs2(Begin, 0);
// printf("End = %d\n", End);
Ans = dis[End];
printf("%d", Ans + 1);
return 0;
}