真的还有好多东西要学啊......
定理:
选取树 $T$ 的任意一个点 $i$ ,则与 $i$ 距离最远的节点 $r$ 必定是树中一条直径的端点.
定理:
树 $T$ 的直径长度一定能表示为树 $T$ 上某个点 $i$ 所引领的子树中,最大深度与次大深度之和.
即, $\exists_{i\in V(T)}\; diameter = LargestDepth(subtree \ o \! f \ i) + SecondLargestDepth(subtree \ o \! f \ i)$
由于直径只有一个值,并且两个深度之和代表了一条路径的长度,
于是有$\forall_{i\in V(T)} \; diameter \ge LargestDepth(subtree \ o \! f \ i) + SecondLargestDepth(subtree \ o \! f \ i)$
AC VIJOS 1476 求在直径上的所有点. 直径可能有多条.
1 #include <cstdio> 2 #include <fstream> 3 #include <iostream> 4 5 #include <cstdlib> 6 #include <cstring> 7 #include <algorithm> 8 #include <cmath> 9 10 #include <queue> 11 #include <vector> 12 #include <map> 13 #include <set> 14 #include <stack> 15 #include <list> 16 17 typedef unsigned int uint; 18 typedef long long int ll; 19 typedef unsigned long long int ull; 20 typedef double db; 21 22 using namespace std; 23 24 inline int getint() 25 { 26 int res=0; 27 char c=getchar(); 28 bool mi=false; 29 while(c<‘0‘ || c>‘9‘) mi=(c==‘-‘),c=getchar(); 30 while(‘0‘<=c && c<=‘9‘) res=res*10+c-‘0‘,c=getchar(); 31 return mi ? -res : res; 32 } 33 inline ll getll() 34 { 35 ll res=0; 36 char c=getchar(); 37 bool mi=false; 38 while(c<‘0‘ || c>‘9‘) mi=(c==‘-‘),c=getchar(); 39 while(‘0‘<=c && c<=‘9‘) res=res*10+c-‘0‘,c=getchar(); 40 return mi ? -res : res; 41 } 42 43 db eps=1e-80; 44 inline bool feq(db a,db b) 45 { return fabs(a-b)<eps; } 46 47 template<typename Type> 48 inline Type avg(const Type a,const Type b) 49 { return a+((b-a)/2); } 50 51 //=================================================================== 52 //=================================================================== 53 //=================================================================== 54 //=================================================================== 55 56 57 const int INF=(1<<30)-1; 58 59 struct edge 60 { 61 int in; 62 edge*nxt; 63 }pool[405000]; 64 edge*et=pool; 65 edge*eds[205000]; 66 void addedge(int i,int j) 67 { et->in=j; et->nxt=eds[i]; eds[i]=et++; } 68 #define FOREACH_EDGE(i,j) for(edge*i=eds[j];i;i=i->nxt) 69 70 int n; 71 72 int dep[205000]; 73 int q[205000],qh,qt; 74 75 int deg[205000]; 76 77 int dia=0; 78 79 int mx[205000]; 80 int mxs[205000]; 81 int mxp[205000]; 82 int uv[205000]; 83 84 int f[205000]; 85 86 int main() 87 { 88 n=getint(); 89 for(int i=1;i<n;i++) 90 { 91 int a=getint(); 92 int b=getint(); 93 addedge(a,b); 94 addedge(b,a); 95 } 96 97 qh=qt=0; 98 q[qt++]=0; 99 memset(dep,0xFF,sizeof(int)*(n+1)); 100 dep[0]=0; 101 while(qh!=qt) 102 { 103 int x=q[qh]; 104 FOREACH_EDGE(i,x) 105 if(dep[i->in]==-1) 106 { 107 f[i->in]=x; 108 dep[i->in]=dep[x]+1; 109 q[qt++]=i->in; 110 deg[x]++; 111 } 112 qh++; 113 } 114 115 memset(mxp,0xFF,sizeof(int)*(n+1)); 116 memset(mx,0xFF,sizeof(int)*(n+1)); 117 memset(mxs,0xFF,sizeof(int)*(n+1)); 118 qh=qt=0; 119 for(int i=0;i<n;i++) 120 if(deg[i]==0) q[qt++]=i; 121 while(qh!=qt) 122 { 123 int x=q[qh]; 124 125 FOREACH_EDGE(i,x) 126 if(i->in!=f[x]) 127 { 128 if(mx[i->in]>mx[x]) 129 { 130 mxs[x]=mx[x]; 131 mx[x]=mx[i->in]; 132 mxp[x]=i->in; 133 } 134 else if(mx[i->in]>mxs[x]) 135 { 136 mxs[x]=mx[i->in]; 137 } 138 } 139 140 deg[f[x]]--; 141 if(deg[f[x]]==0) 142 { q[qt++]=f[x]; } 143 144 mx[x]++; 145 mxs[x]++; 146 147 qh++; 148 } 149 150 qh=qt=0; 151 uv[0]=0; 152 FOREACH_EDGE(i,0) 153 q[qt++]=i->in; 154 155 while(qh!=qt) 156 { 157 int x=q[qh]; 158 159 uv[x]=max( uv[f[x]], 160 x==mxp[f[x]] ? mxs[f[x]] : mx[f[x]]) +1; 161 162 FOREACH_EDGE(i,x) 163 if(i->in!=f[x]) q[qt++]=i->in; 164 165 qh++; 166 } 167 168 for(int i=0;i<n;i++) 169 dia=max(dia,mx[i]+mxs[i]); 170 171 172 for(int i=0;i<n;i++) 173 if(mx[i]+uv[i]==dia || mx[i]+mxs[i]==dia) printf("%d\n",i); 174 175 return 0; 176 }
时间: 2024-10-06 00:50:41