仔细观察可以发现,这个规划路径很像树链剖分
树链剖分的经典定理:任意一个点到根的所经过轻边不超过logn
而这个规划路径所走公路相当于轻边,也就是说,不便利度不会很大
那么直接dp即可,设f[x,i,k]表示以x为根的子树,不便利度不超过i,且x向下连了k[0,2]条边的方案数
根据增量法的思想,不难从孩子转移到父亲
注意这里取模等于0和没有方案的区别要注意一下
1 type node=record 2 po,next:longint; 3 end; 4 5 var e:array[0..400010] of node; 6 f:array[0..100010,-1..12,0..2] of int64; 7 p:array[0..100010] of longint; 8 v:array[0..100010] of boolean; 9 mo,n,m,i,x,y,len:longint; 10 11 procedure add(x,y:longint); 12 begin 13 inc(len); 14 e[len].po:=y; 15 e[len].next:=p[x]; 16 p[x]:=len; 17 end; 18 19 function get(x:int64):int64; 20 begin 21 if (x>0) and (x mod mo=0) then exit(mo) 22 else exit(x mod mo); 23 end; 24 25 procedure dfs(x:longint); 26 var i,y,j:longint; 27 s1,s0:int64; 28 begin 29 for i:=0 to 12 do 30 f[x,i,0]:=1; 31 i:=p[x]; 32 v[x]:=true; 33 while i<>0 do 34 begin 35 y:=e[i].po; 36 if not v[y] then 37 begin 38 dfs(y); 39 for j:=0 to 12 do 40 begin 41 s1:=f[y,j,0]+f[y,j,1]; 42 s0:=f[y,j-1,0]+f[y,j-1,1]+f[y,j-1,2]; 43 f[x,j,2]:=get(f[x,j,2]*s0+f[x,j,1]*s1); 44 f[x,j,1]:=get(f[x,j,1]*s0+f[x,j,0]*s1); 45 f[x,j,0]:=get(f[x,j,0]*s0); 46 end; 47 end; 48 i:=e[i].next; 49 end; 50 end; 51 52 begin 53 readln(n,m,mo); 54 for i:=1 to m do 55 begin 56 readln(x,y); 57 add(x,y); 58 add(y,x); 59 end; 60 if m<n-1 then 61 begin 62 writeln(-1); 63 writeln(-1); 64 halt; 65 end; 66 dfs(1); 67 for i:=0 to 12 do 68 if f[1,i,0]+f[1,i,1]+f[1,i,2]>0 then 69 begin 70 writeln(i); 71 writeln((f[1,i,0]+f[1,i,1]+f[1,i,2]) mod mo); 72 halt; 73 end; 74 writeln(-1); 75 writeln(-1); 76 end.
时间: 2024-11-05 12:58:03