bzoj2657 [Zjoi2012]旅游(journey)
Gerw说凸多边形的三角剖分是一棵树,并且可以转二叉树,因此卡特兰数可以……
发现一条边只能连接两个三角形,所以可以把三角形当做树的结点,相邻的连边
求证:连接两个三角形的线段经过的三角形等同于树上两个三角形路径上的所有点
我想说,证明好麻烦啊。。。不过还是想表达一下我的看法。。。
首先,题目说(一个城市被当做经过当且仅当其与线路有至少两个公共点)
于是,这条线段经过一个三角形必定穿过三条边中的一条,那么可以从另外两条边中的一条穿出而非顶点(不是最优,想一想为什么)
现在就是关键时刻了,如图现在有一条穿过这两个三角形的线段,那么就不可能有另外一条线段能从另一条边穿入下方的三角形。
因为原图是凸多边形,因此这六个点(原图的点集的一个子集)必定形成凸包,
那么角CDE就必须小于180o那么就不可能存在线段能穿过CD、DE边连接两个三角形,也就是说,两个三角形有且仅有一条路径能互相到达
那么这个图就满足树的性质……
然后就可以用map来连边,找出树的直径就好
不知为什么,map里扔自己的结构体迭代器就取不出来元素。。。(雾
1 #include<algorithm> 2 #include<iostream> 3 #include<cstdlib> 4 #include<cstring> 5 #include<cstdio> 6 #include<string> 7 #include<cmath> 8 #include<ctime> 9 #include<queue> 10 #include<stack> 11 #include<map> 12 #include<set> 13 #define rre(i,r,l) for(int i=(r);i>=(l);i--) 14 #define re(i,l,r) for(int i=(l);i<=(r);i++) 15 #define Clear(a,b) memset(a,b,sizeof(a)) 16 #define inout(x) printf("%d",(x)) 17 #define douin(x) scanf("%lf",&x) 18 #define strin(x) scanf("%s",(x)) 19 #define LLin(x) scanf("%lld",&x) 20 #define op operator 21 #define CSC main 22 typedef unsigned long long ULL; 23 typedef const int cint; 24 typedef long long LL; 25 using namespace std; 26 void inin(int &ret) 27 { 28 ret=0;int f=0;char ch=getchar(); 29 while(ch<'0'||ch>'9'){if(ch=='-')f=1;ch=getchar();} 30 while(ch>='0'&&ch<='9')ret*=10,ret+=ch-'0',ch=getchar(); 31 ret=f?-ret:ret; 32 } 33 int n; 34 int sta[7],top; 35 int head[200020],next[400040],zhi[400040],ed; 36 void add(int a,int b) 37 { 38 next[++ed]=head[a],head[a]=ed,zhi[ed]=b; 39 next[++ed]=head[b],head[b]=ed,zhi[ed]=a; 40 } 41 int dis[200020]; 42 void dfs(int x,int fa) 43 { 44 for(int i=head[x];i;i=next[i])if(zhi[i]!=fa) 45 dis[zhi[i]]=dis[x]+1,dfs(zhi[i],x); 46 } 47 map<pair<int,int>,int>s; 48 map<pair<int,int>,int>::iterator it; 49 int q[4],a,b,c; 50 int main() 51 { 52 inin(n); 53 re(i,1,n-2) 54 { 55 inin(q[1]),inin(q[2]),inin(q[3]); 56 a=max(q[1],max(q[2],q[3])); 57 b=min(q[1],min(q[2],q[3])); 58 if(q[1]!=a&&q[1]!=b)q[2]=q[1]; 59 else if(q[3]!=a&&q[3]!=b)q[2]=q[3]; 60 else ; 61 q[3]=a,q[1]=b; 62 63 it=s.find(make_pair(q[1],q[2])); 64 if(it!=s.end())add(it->second,i),s.erase(it); 65 else s[make_pair(q[1],q[2])]=i; 66 67 it=s.find(make_pair(q[1],q[3])); 68 if(it!=s.end())add(it->second,i),s.erase(it); 69 else s[make_pair(q[1],q[3])]=i; 70 71 it=s.find(make_pair(q[2],q[3])); 72 if(it!=s.end())add(it->second,i),s.erase(it); 73 else s[make_pair(q[2],q[3])]=i; 74 } 75 dis[1]=1; 76 dfs(1,0); 77 int Max=0,o; 78 re(i,1,n-2)if(Max<dis[i])Max=dis[i],o=i; 79 dis[o]=1; 80 dfs(o,0); 81 re(i,1,n)Max=max(Max,dis[i]); 82 printf("%d",Max); 83 return 0; 84 }