![ישן](https://static.fresh.co.il/images/vBulletin/statusicon/post_old.gif)
30-12-2007, 19:37
|
![צלמית המשתמש של maxim k](image.php?u=95174&dateline=1191934585) |
|
|
חבר מתאריך: 05.08.06
הודעות: 2,860
|
|
1. אתה יכול להוסיף בO(N) מצביע לאב ולכן זה לא משנה. בכל מקרה אתה לא ציינת בהודעה שמדובר בעץ ממויין. לכן נאלצתי להביא פיתרון כללי יותר שיעבוד על כל עץ בינארי.
2. אני אנסה להסביר מזווית אחרת.. בכל מסלול שאורכו כאורך הקוטר (נקרא לו גם קוטר, לצורך נוחות) קיים צומת v שמחלק את המסלול לשני מסלולים, ואף אחד מהם אינו יוצא כלפי מעלה. (הוכחה בכמה מילים: נבחר ממסלול הקוטר את הקודקוד שנמצא הכי גבוה בעץ. נניח בשלילה שהטענה אינה נכונה. אז מסלול הקוטר ממשיך דרלך הקודקוד הנ"ל כלפי מעלה, אז הצומת הראשון במעלה המסלול שייך למסלול המקורי וגבוה יותר מהקודקוד שהנחנו שהוא הגבוה ביותר - סתירה). מה אפשר להגיד על v הזה? נקרא לחלקי מסלול הקוטר שיוצאים ממנו "ימני" ו"שמאלי", בהתאמה לבנים של v שממנו הם ממשיכים (כמובן יכול להיות שאין לו בן ימני/שמאלי ואז המסלול הימני/שמאלי ריק). כמובן סכום אורך המסלול הימני ואורך המסלול שמאלי הוא הקוטר עצמו. בנוסף, קל להוכיח שהמסלול הימני/שמאלי הוא המסלול הארוך ביותר שיורד מהבן הימני/שמאלי של v (לה"כ נתייחס רק לימני: נניח בשלילה שלא כך הדבר, אז קיים מסלול אחר ארוך יותר, אבל אם נחבר אותו למסלול השמאלי של v נקבל מסלול ארוך יותר מהקוטר המקורי - סתירה). כעת פשוט להבין שכל מה שצריך לעשות הוא לסרוק רקורסיבית את כל הקודקודים, לחשב עבור כל אחד את אורך המסלול הימני הארוך ביותר שיוצא מהם ואת אורך המסלול השמאלי הארוך ביותר שיוצא מהם. הסכום המקסימלי של שני אורכים אלו עבור קודקוד מסויים הוא הקוטר (כי בהכרח עברנו בדרך גם על פני הקודקוד v הנ"ל, ובהכרח סכום הערכים האלה אצלו שווה לאורך הקוטר ומקסימלי לגבי שאר הקודקודים (אחרת זה לא היה קוטר)). אפשר לעשות את זה רקורסיבית בO(N) סה"כ.
נערך לאחרונה ע"י maxim k בתאריך 30-12-2007 בשעה 19:45.
|