[ZJOI2012]旅游
题目:
这题意。。。还以为他说的线段是路径
写了好久的dp。。写不出来
看了网上的题解。。才知道就是两点连线
然后就是一般的平面图转对偶图的思想
然后算一下边数发现是颗树,求一下直径就好了
代码:
#include <bits/stdc++.h> using namespace std; #define mo 5000007 int n,c,d,e,l,ans,head[300000]; int len1[300000],len2[300000]; struct re{ int x,y,c; }pd[5100000]; struct { int a,b; }a[410000]; void insert(int x,int y,int z) { int tmp=((200000*x+y)%mo+mo)%mo; while (pd[tmp].x) tmp=tmp%mo+1; pd[tmp].x=x; pd[tmp].y=y; pd[tmp].c=z; } int find(int x,int y) { int tmp=((200000*x+y)%mo+mo)%mo; while (!(pd[tmp].x==x&&pd[tmp].y==y)&&pd[tmp].x) tmp=tmp%mo+1; if (pd[tmp].x==x&&pd[tmp].y==y) return(pd[tmp].c); else return -1; } void arr(int x,int y) { a[++l].a=head[x]; a[l].b=y; head[x]=l; } void dfs(int x,int fa) { int u=head[x]; while (u) { int v=a[u].b; if (v!=fa) { dfs(v,x); if (len1[v]>len1[x]) { len2[x]=len1[x]; len1[x]=len1[v]; } else if (len1[v]>len2[x]) { len2[x]=len1[v]; } } u=a[u].a; } len1[x]++; ans=max(ans,len1[x]+len2[x]); } int main() { cin>>n; for (int i=1;i<=n-2;i++) { cin>>c>>d>>e; int x1=find(c,d); int x2=find(c,e); int x3=find(d,e); if (x1==-1) insert(c,d,i),insert(d,c,i); else arr(x1,i),arr(i,x1); if (x2==-1) insert(c,e,i),insert(e,c,i); else arr(x2,i),arr(i,x2); if (x3==-1) insert(d,e,i),insert(e,d,i); else arr(x3,i),arr(i,x3); } dfs(1,0); cout<<ans; }