bzoj 2657 [Zjoi2012]旅游(journey…

来源:互联网 发布:创意摆件 知乎 编辑:程序博客网 时间:2024/06/05 04:43

Description

    到了难得的暑假,为了庆祝小白在数学考试中取得的优异成绩,小蓝决定带小白出去旅游~~

   经过一番抉择,两人决定将T国作为他们的目的地。T国的国土可以用一个凸N边形来表示,N个顶点表示N个入境/出境口。T国包含N-2个城市,每个城市都是顶点均为N边形顶点的三角形(换而言之,城市组成了关于T国的一个三角剖分)两人的旅游路线可以看做是连接N个顶点中不相邻两点的线段

bzoj <wbr>2657 <wbr>[Zjoi2012]旅游(journey)

为了能够买到最好的纪念品,小白希望旅游路线上经过的城市尽量多。作为小蓝的好友,你能帮帮小蓝吗?

Input

 每个输入文件中仅包含一个测试数据。
第一行包含两个由空格隔开的正整数NN的含义如题目所述。
    接下来有N-2行,每行包含三个整数 p,q,r,表示该城市三角形的三个顶点的编号(T国的N个顶点按顺时间方向从1n编号)

Output

     输出文件共包含1行,表示最多经过的城市数目。(一个城市被当做经过当且仅当其与线路有至少两个公共点)

Sample Input

6
1 2 4
2 3 4
1 4 5
1 5 6

Sample Output

4

HINT

4<=N<=200000

 
 
把每个相邻三角形连一条边,求出最长链。
这题真是神级构图啊有木有!!!连完边后就是一棵华丽丽的树啊!!!因为是凸多边形,所以两个三角形之间通过公共边相连的若干三角形都能被这两个三角形的两个顶点的连线交到。不然就会产生大于180的内角。(不知道有没有YY错。。。较弱,没有严格证明过。。。)
构图的时候花了点时间,最终YY出了一个华丽丽的分治~~~分治+人工栈。很少敲这么趣味的代码嗯、、不过模拟深搜还是颇直观的,打着很顺、、
怀着对RE的极度崇敬,直接打了个人工栈,XX的交上去还是RE。。。就是卡pas啊。。冤死了。。
本机测试还是很优秀的、、都是0.2ms出解的。。。
 
code:
program bzoj_2657;
var a,b,c,stack:array[1..200000] of longint;
   f:array[0..200000] of longint;
   ans,n:longint;
//==============================================================
procedure swap(var x,y:longint);
var tt:longint;
begin
  tt:=x; x:=y; y:=tt;
end;
//==============================================================
procedure qsort(l,r:longint);
var k1,k2,i,j:longint;
begin
  k1:=a[(l+r) shr 1]; k2:=b[(l+r) shr 1];
  i:=l; j:=r;
  repeat
    while(a[i]<k1) or ((a[i]=k1) and(b[i]>k2)) do inc(i);
    while(a[j]>k1) or ((a[j]=k1) and(b[j]<k2)) do dec(j);
    ifi<=j then
    begin
     swap(a[i],a[j]); swap(b[i],b[j]);
     swap(c[i],c[j]); inc(i); dec(j);
    end;
  until i>j;
  if l<j then qsort(l,j);
  if i<r then qsort(i,r);
end;
//==============================================================
procedure init;
var i:longint;
begin
  readln(n); dec(n,2);
  for i:=1 to n do
  begin
   readln(a[i],b[i],c[i]);
    ifb[i]<a[i] then swap(b[i],a[i]);
    ifc[i]<a[i] then swap(c[i],a[i]);
    ifb[i]<c[i] then swap(b[i],c[i]);
  end; qsort(1,n);
end;
//==============================================================
procedure update(x,y:longint);
begin
  if y=0 then exit;
  if f[x]+f[y]+1>ans then
   ans:=f[x]+f[y]+1;
  if f[x]>f[y] thenf[y]:=f[x];
end;
//==============================================================
procedure main;
var tot,top,now,fa:longint;
begin
  fillchar(f,sizeof(f),0);
  stack[1]:=1; a[n+1]:=n+3;
  tot:=2; top:=1;
  while top>0 do
  begin
   now:=stack[top]; fa:=stack[top-1];
    ifa[tot]>=b[now] then
    begininc(f[now]);
     update(now,fa); dec(top); continue;
    end;inc(top); stack[top]:=tot; inc(tot);
  end; writeln(ans);
end;
//==============================================================
begin
  assign(input,'journey.in'); reset(input);
  assign(output,'journey.out');rewrite(output);
  init;
  main;
  close(input); close(output);
end.
 
0 0