这道题讨论了好久,一直想不明白,如果按传统的随便某一个点出发找最长链,再回头,K=2 的时候赋了-1就没法用这种方法找最长链了,于是乎,更强的找最长链的方法就来了。。类似于DP的东西吧。先上代码:
1 const maxn=100002; 2 type 3 node=record 4 f,t,l:longint; 5 end; 6 var n,k,i,j,ans,num,f,t,diameter,s,sum:longint; 7 b:array[0..2*maxn] of node; 8 head,go1,go2:array[0..maxn] of longint; 9 procedure swap(var a,b:longint); 10 var tem:longint; 11 begin 12 tem:=a; a:=b; b:=tem; 13 end; 14 procedure insert(num,f,t:longint); 15 begin 16 b[num].f:=head[f]; 17 b[num].t:=t; 18 b[num].l:=1; 19 head[f]:=num; 20 end; 21 function dfs(x,f:longint):longint; 22 var nowe,max1,max2,tem:longint; 23 begin 24 max1:=0; max2:=0; //tem:=0; 25 nowe:=head[x]; 26 while nowe<>0 do 27 begin 28 if b[nowe].t=f then 29 begin 30 nowe:=b[nowe].f; 31 continue; 32 end; 33 tem:=dfs(b[nowe].t,x)+b[nowe].l; 34 if tem>max1 then begin 35 go2[x]:=go1[x]; 36 go1[x]:=nowe; 37 max2:=max1; 38 max1:=tem; 39 end 40 else if tem>max2 then 41 begin 42 go2[x]:=nowe; 43 max2:=tem; 44 end; 45 nowe:=b[nowe].f; 46 end; 47 if diameter<max1+max2 then 48 begin 49 diameter:=max1+max2; 50 s:=x; 51 end; 52 exit(max1); 53 end; 54 begin 55 readln(n,k); 56 for i:=1 to n-1 do 57 begin 58 readln(f,t); 59 insert(i*2-1,f,t); 60 insert(i*2,t,f); 61 end; 62 ans:=2*(n-1); 63 diameter:=0; 64 sum:=dfs(1,0); 65 ans:=ans-diameter+1; 66 if k>1 then 67 begin 68 diameter:=0; 69 i:=go1[s]; 70 while i<>0 do 71 begin 72 b[i].l:=-1; 73 i:=go1[b[i].t]; 74 end; 75 i:=go2[s]; 76 while i<>0 do 77 begin 78 b[i].l:=-1; 79 i:=go1[b[i].t]; 80 end; 81 t:=dfs(1,0); 82 ans:=ans-diameter+1; 83 end; 84 writeln(ans); 85 end.
1 int diameter,s; //树的直径为diameter,直径的起点是s 2 int son1[MAXV],son2[MAXV]; //记录最长路与次长路的路径 3 4 int DFS(int u,int fa) 5 { 6 int max1=0,max2=0; //与当前点相连的最长路与次长路 之和为不过fa的最长链,或者与fa相连并 //加上与fa相连边权值,作为连接fa可能的max1 或 max2 7 for(int p=head[u];p!=-1;p=edges[p].next) 8 { 9 int v=edges[p].v; 10 if(v==fa) continue; //一直往下走,直到叶子节点 11 int nowh=DFS(v,u)+edges[p].w; 12 if(nowh>max1) max2=max1,son2[u]=son1[u],max1=nowh,son1[u]=p; 13 else if(nowh>max2) max2=nowh,son2[u]=p; 14 } 15 if(diameter<max1+max2) diameter=max1+max2,s=u; 16 return max1; 17 }
而复杂度也是 O(n)的。
(转载请注明出处:http://www.cnblogs.com/Kalenda/)
时间: 2024-10-05 21:21:17