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

来源:互联网 发布:淘宝网人工客服热线 编辑:程序博客网 时间:2024/05/16 04:37

题目在这里

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

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

这里写图片描述
省略号就是一堆能让它连起来的三角形,那么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;}
0 0
原创粉丝点击