背景介紹
弗蘭德,我不知道這個地方對我意味著什麼。這裡是一切開始的地方。3年前,還是個什麼都沒見過的少年,來到弗蘭德的樹下,走進了封閉的密室,扭動的封塵已久機關,在石板上知道了這個世界最角落的最陰暗的東西。那種事情,從未忘懷,從未動搖,我還記得,那一天,我,裡修,第一次拔起了劍……
弗蘭德的密室裡,機關上方畫著兩棵樹的字樣,機關下方是乙個有數字的刻度……
弗蘭德最高的兩棵樹,只要知道兩棵樹的共同的相似度就行了……
給定兩棵有根樹,可以任意刪除兩棵樹上的節點(刪除一棵節點必須保證該節點的子樹內的所有節點也必須要被刪除,換一種說法,刪除後的樹必須聯通並形成一棵樹,且根節點不能被刪除),使得刪除後的兩棵樹同構,這兩棵樹有乙個共同大小,即樹的size,最大化同構的樹的size即為機關的答案……
注:兩棵同構的樹要滿足以下條件:
1、兩棵樹節點個數相等。
2、兩棵樹的以根節點的兒子為根子樹對應同構。如下圖,為兩棵同構的有根樹。
如下圖,為兩棵同構的有根樹。
給出兩個有根樹,求出最大的同構的樹的節點個數
同構定義:
1、兩棵樹節點個數相等。
2、兩棵樹的以根節點的兒子為根子樹對應同構。
照搬題目qaq
很明顯是乙個樹形dp
看到資料
1 ≤ n ≤ 1000可以想到用o(n
2)o(n^2)
o(n2)來求
設f [i
][j]
f[i][j]
f[i][j
]表示第1棵樹到了第i
ii個點,第2棵樹到了第j
jj個點的最大相似度(即節點個數)
注意到資料還有一點就是
資料保證兩棵樹上每個節點的度均不超過5出題人好良心
那麼對於當前這個f[i
][j]
f[i][j]
f[i][j
],可以思考暴力轉移
暴力將第1棵樹中i
ii的兒子和第2棵樹中j
jj的兒子連線起來,時間複雜度是o(5
!)o(5!)
o(5!
)那麼f[i
][j]
f[i][j]
f[i][j
]就等於max
(f[i
的兒子]
[j的兒
子])+
1max(f[i的兒子][j的兒子])+1
max(f[
i的兒子
][j的
兒子])
+1總的時間複雜度是o(5
!∗n2
)o(5!*n^2)
o(5!∗n
2)
#include
#include
using
namespace std;
int n,m,i,x,y,one,two,ans,tree1[
1005][
10],tree2[
1005][
10],f[1005][
1005];
bool b[
1005];
void
dg2(
int now,
int sum)
dg2(now+
1,sum)
; bj=
false
;for
(i=1
;i<=tree2[two][0
];i++)if
(bj==
false
) f[one]
[two]
=max
(f[one]
[two]
,sum);}
void
dg1(
int now)
for(i=
1;i<=tree1[now][0
];i++
)dg1
(tree1[now]
[i])
;for
(i=1
;i<=m;i++
) one=now;
two=i;
dg2(1,
0); f[now]
[i]++;if
(now==
1&&i==
1) ans=
max(ans,f[now]
[i]);}
}int
main()
for(i=
1;i)dg1(1
);printf
("%d\n"
,ans)
;fclose
(stdin);
fclose
(stdout);
return0;
}
JZOJ7月16日提高組T1 質數
題解定義質數為因數只含1和其本身的數,對於n組詢問,試判斷每個數是否為素數。第一行乙個正整數n,表示有n組詢問。接下來n行,每行乙個正整數m,表示詢問m是否為質數。輸出n行,每行乙個字串。若是質數則輸出 prime 若不是質數則輸出 not prime 52 1089807289 903248294...
JZOJ7月23日提高組T1 同餘
題解有一同餘方程 滿足p pp是質數,xi,jx xi,j 在0 p pp之間 問滿足同餘方程的方案數模乙個給出的數後的結果 手模資料或者打表可以發現,當c 0 c 0c 0時,所有答案都是一樣的 那麼就可以分成c 0 c 0c 0和c 0c 0 c 0兩種情況討論 轉移一下就好了 include ...
JZOJ7月25日提高組T1 挑竹籤
挑竹籤 小時候的遊戲 夏夜,早苗和諏訪子在月光下玩起了挑竹籤這一經典的遊戲。挑竹籤,就是在桌上擺上一把竹籤,每次從最上層挑走一根竹籤。如果動了其他的竹籤,就要換對手來挑。在所有的竹籤都被挑走之後,誰挑走的竹籤總數多,誰就勝了。身為神明的諏訪子自然會讓早苗先手。為了獲勝,早苗現在的問題是,在諏訪子出手...