您的位置:首页 > 其它

[bzoj 2657] [Zjoi2012]旅游(journey)

2015-11-26 17:10 459 查看
题目在这里

考虑多边形上的每个剖出来的三角形,将每个三角形和与它相邻的三角形连边(即有两个公共点)。这样子构出来的图是一棵树。

证明:显然这个图联通,且不会出现环的情况,否则由于它是正多边形,有环的话那个中间节点一定会被若干个三角形包裹起来,那么它不可能是凸多边形的顶点。如下图:



省略号就是一堆能让它连起来的三角形,那么O点就一定不可能是凸多边形的顶点(美术天赋糟糕,勿吐槽)。

这样子的话,所谓最长的旅行路线,其实就是树上最长链了。直接两遍bfs搞定。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <ctime>
using namespace std;

const int MAXN=200005;

int n,tot,ttot,end,fst[MAXN],pre[MAXN*2],to[MAXN*2],w[MAXN],head,tail,Q[MAXN];
bool vis[MAXN];
struct Edge
{
int from,to,idx;
Edge() {} Edge (int _from,int _to,int _idx) { from=_from,to=_to,idx=_idx; }
}E[MAXN*3];

bool cmp(const Edge &a,const Edge &b) { return ( (a.from<b.from) || (a.from==b.from && a.to<b.to) ); }
bool operator == (Edge a,Edge b) { return ( a.from==b.from && a.to==b.to ); }

void E_add(int a,int b,int c,int idx)
{
if (a>b) swap(a,b); if (a>c) swap(a,c); if (b>c) swap(b,c);
E[++tot]=Edge(a,b,idx),E[++tot]=Edge(a,c,idx),E[++tot]=Edge(b,c,idx);
}

void add(int x,int y)
{
pre[++ttot]=fst[x],fst[x]=ttot,to[ttot]=y;
pre[++ttot]=fst[y],fst[y]=ttot,to[ttot]=x;
}

int Get()
{
char ch; int v=0; bool f=false;
while (!isdigit(ch=getchar())) if (ch=='-') f=true; v=ch-48;
while (isdigit(ch=getchar())) v=v*10+ch-48;
if (f) return -v;else return v;
}

void bfs(int S)
{
for (int i=1;i<=n;i++) vis[i]=false,w[i]=0;
head=tail=1,w[S]=1,Q[tail++]=S,vis[S]=true;
while (head!=tail)
{
int x=Q[head++];
for (int i=fst[x];i;i=pre[i])
{
int y=to[i];
if (!vis[y]) w[y]=w[x]+1,vis[y]=true,Q[tail++]=y;
}
}
end=1;
for (int i=2;i<=n;i++) if (w[i]>w[end]) end=i;
}

int main()
{
freopen("journey.in","r",stdin);
freopen("journey.out","w",stdout);
n=Get(); int a,b,c; tot=ttot=0; n-=2;
for (int i=1;i<=n;i++) a=Get(),b=Get(),c=Get(),E_add(a,b,c,i);

sort(E+1,E+1+tot,cmp);
for (int i=1;i<=tot-1;i++) if (E[i]==E[i+1]) add(E[i].idx,E[i+1].idx);
bfs(1); bfs(end);
printf("%d\n",w[end]);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: