[bzoj 2657] [Zjoi2012]旅游(journey)
2015-11-26 17:10
459 查看
题目在这里
考虑多边形上的每个剖出来的三角形,将每个三角形和与它相邻的三角形连边(即有两个公共点)。这样子构出来的图是一棵树。
证明:显然这个图联通,且不会出现环的情况,否则由于它是正多边形,有环的话那个中间节点一定会被若干个三角形包裹起来,那么它不可能是凸多边形的顶点。如下图:
![](http://img.blog.csdn.net/20151126170610829)
省略号就是一堆能让它连起来的三角形,那么O点就一定不可能是凸多边形的顶点(美术天赋糟糕,勿吐槽)。
这样子的话,所谓最长的旅行路线,其实就是树上最长链了。直接两遍bfs搞定。
考虑多边形上的每个剖出来的三角形,将每个三角形和与它相邻的三角形连边(即有两个公共点)。这样子构出来的图是一棵树。
证明:显然这个图联通,且不会出现环的情况,否则由于它是正多边形,有环的话那个中间节点一定会被若干个三角形包裹起来,那么它不可能是凸多边形的顶点。如下图:
省略号就是一堆能让它连起来的三角形,那么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; }
相关文章推荐
- kvm
- rpm、yum(转)
- 老李分享:webservice是什么?
- 微信扫码登录网站
- [Javascript] Data Type & Summary
- C++获取目录下所有图像文件的文件名
- 数据存储
- Linux下redis的安装
- ul li 下的元素内容垂直居中
- 1.6 Performance
- 提交表单时的等待(loading)效果
- 老李分享:测试架构师
- JAVA 十六进制与字符串的转换
- final
- 编写调用新浪微博API的Java程序来发送微博
- Spring什么时候实例化bean
- UI_程序的基本结构
- Android 个推 Clientid,PushManagerReceiver
- 快速排序分析
- Xcode如何在自己的工程中引入另外一个工程及相关错误的解决办法