仔细观察可以发现,这个规划路径很像树链剖分

树链剖分的经典定理:任意一个点到根的所经过轻边不超过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.
View Code

 

posted on 2015-06-30 17:04  acphile  阅读(136)  评论(0编辑  收藏  举报