题目大意:给出一个凸多边形的三角剖分图,每一个三角形代表一个城市,现在连接这个图中的两个点,问最多能够经过多少个城市。
思路:浙江都是一帮神么。。
这题给的条件简直是不知所云啊。。转化十分巧妙。因为每个凸n边形经过三角剖分之后会出现n - 2个三角形,任意一条边只会成为两个城市的公共边或者整个多边形的边。不难推出两个城市的公共边是n - 3条,也就是说把公共边看成是新图的边的话,就会新图就会构成一颗树。之后就是很水的树的直径了。。。
CODE:
#include <map>
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAX 200010
using namespace std;
#define max(a,b) ((a) > (b) ? (a):(b))
#define min(a,b) ((a) < (b) ? (a):(b))
int points;
map<pair<int,int>,int> G;
int head[MAX],total;
int next[MAX << 1],aim[MAX << 1];
inline void Add(int x,int y)
{
next[++total] = head[x];
aim[total] = y;
head[x] = total;
}
int f[MAX];
void BFS(int start)
{
static bool v[MAX];
memset(v,false,sizeof(v));
memset(f,0x3f,sizeof(f));
static queue<int> q;
while(!q.empty()) q.pop();
q.push(start);
f[start] = 0;
while(!q.empty()) {
int x = q.front(); q.pop();
v[x] = true;
for(int i = head[x]; i; i = next[i]) {
if(v[aim[i]]) continue;
f[aim[i]] = f[x] + 1;
q.push(aim[i]);
}
}
}
int main()
{
cin >> points;
for(int x,y,z,i = 1; i <= points - 2; ++i) {
scanf("%d%d%d",&x,&y,&z);
pair<int,int> e(min(x,y),max(x,y));
if(G.find(e) == G.end())
G[e] = i;
else {
Add(i,G[e]);
Add(G[e],i);
}
e = make_pair(min(y,z),max(y,z));
if(G.find(e) == G.end())
G[e] = i;
else {
Add(i,G[e]);
Add(G[e],i);
}
e = make_pair(min(x,z),max(x,z));
if(G.find(e) == G.end())
G[e] = i;
else {
Add(i,G[e]);
Add(G[e],i);
}
}
BFS(1);
int p = 0;
f[0] = 0;
for(int i = 1; i <= points - 2; ++i)
if(f[i] > f[p])
p = i;
BFS(p);
cout << *max_element(f + 1,f + points - 1) + 1 << endl;
return 0;
}