三角剖分转对偶图之后形成了树,问题转化为求树上最长链
证明见14年论文
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<map> #define rep(i,l,r) for(int i=l;i<=r;i++) #define per(i,r,l) for(int i=r;i>=l;i--) #define mmt(a,v) memset(a,v,sizeof(a)) #define tra(i,u) for(int i=head[u];i;i=e[i].next) using namespace std; const int N=200000+5; struct Edge{int to,next;}e[N<<1]; int head[N],cnt; void ins(int u,int v){e[++cnt]=(Edge){v,head[u]};head[u]=cnt;} void insert(int u,int v){ins(u,v);ins(v,u);} int dp(int u,int fa,int &ans){ int mx=0; tra(i,u){ int v=e[i].to;if(v==fa)continue; int tmp=dp(v,u,ans); ans=max(ans,mx+tmp+1); mx=max(mx,tmp+1); } return mx; } typedef pair<int,int> pr; #define mk(x,y) make_pair(x,y) map<pr,int>mp; void add(int a,int b,int i){ if(a>b)swap(a,b); pr p=mk(a,b); if(mp.count(p))insert(i,mp[p]); else mp[p]=i; } int main(){ //freopen("a.in","r",stdin); int n;scanf("%d",&n); rep(i,1,n-2){ int x,y,z;scanf("%d%d%d",&x,&y,&z); add(x,y,i);add(y,z,i);add(x,z,i); } int ans=0; dp(1,-1,ans); printf("%d\n",ans+1); return 0; }