ZJU2013 Labyrinth 樹的最長路

2021-04-15 04:20:31 字數 1992 閱讀 9045

題目描述:

乙個n*m的地圖, 求出相距最遠的兩個空地間之間的距離。保證地圖中任意兩個空地之間有且僅有一條路徑。n,m<1000

分析:

可以看出,整個地圖的路徑可以構成一棵樹。題目就是要求這棵樹中距離最遠的兩個點

假設我們已經把這棵樹建好了,我用了乙個很短的遞迴函式maxlen求出了這個樹的最長路,這個遞迴函式返回以頂點p為根的樹的深度

1.若p是葉子,則返回0。

2.若p不是葉子,則計算它的每個子樹的深度m=maxlen(son[i])+len[p,son[i]](注意,子樹的個數不會超過3)

3.若子樹的深度最大和次大之和大於ans,則更新ans的值。ans是外部變數記錄當前的最長路。

4.返回最大的子樹深度。

這個函式不到20行。要注意的是由於是矩陣地圖,所以任意乙個點相鄰的空地最多4個,看作有向樹的話,子樹最多3個。在儲存的時候可以節省一些空間和時間。

現在要做的就是把地圖轉換為樹。

轉換的時候使用廣度優先搜尋,也沒太多技巧。只有遇到死胡同和岔路的點,才把它加入到樹的節點中。

貼一下**,2秒多ac的:

/*zju2013 labyrinth

*/#include

#include

#define n 1002

#define clr(a) memset(a,0,sizeof(a))

struct nodepoint;

typedef struct nodepoint node;

struct nodesearch;

typedef struct nodesearch point;

int dir[2]=,,,};

int c,r;

int ans;

char a[n][n];

char e[n][n];

node b[n*n/2][4];

point d[n*n/2];

int out(int x,int y)

int neighbour(int x0,int y0,char ch)

return c;

}//creat a tree

int creattree(char a[n],node b[4])

//each dir

for(k=0;k<4;k++)

}p++;

}//end bfs

return m;

}//return the max depth under node p

int maxlen(int p)

else if(m>=m2)

}len=m1+m2;

if(len>ans) ans=len;

return m1;

}int main()

//system("pause");

return 0;

}sample input

33 3

####.#

###7 6

#######

#.#.###

#.#.###

#.#.#.#

#.....#

#######

7 6#######

#.....#

#.#.###

#.#.#.#

#.#...#

#######

sample output

maximum rope length is 0.

maximum rope length is 8.

maximum rope length is 11.

SDOI2013 直徑(樹的直徑)

小q最近學習了一些圖論知識。根據課本,有如下定義。樹 無迴路且連通的無向圖,每條邊都有正整數的權值來表示其長度。如果一棵樹有n個節點,可以證明其有且僅有n 1 條邊。路徑 一棵樹上,任意兩個節點之間最多有一條簡單路徑。我們用 dis a,b 表示點a和點b的路徑上各邊長度之和。稱dis a,b 為a...

求樹的直徑 樹中最長路

對於一顆有邊權的樹,它的直徑表示樹中最遠的兩個節點之間的距離,可以通過兩次深搜 廣搜 來求出直徑 從任意起點s開始,求出到s的最遠的節點node,然後再從node開始求出到node最遠的節點,搜尋的過程中更新節點的值和距離,貌似還可以用樹形dp來求,剛剛做的一道題,當時感覺是兩倍的權值和減去乙個最遠...

基環樹的最長鏈

本題給定幾個基環樹的森林,求每棵基環樹的直徑長度之和 思路 先單獨考慮一棵基環樹,先dfs找環 也可tarjan 先把每個環上的點向外擴充套件,找出它們每棵子樹的直徑,用樹型dp處理,接著拆環成鏈,再複製一倍的鏈長,在環上跑,用單調佇列維護即可,但是維護前還需要預處理下直徑字首和,否則會爆時間。來自...