noip 2003 傳染病控制

2022-05-10 03:57:52 字數 2279 閱讀 7462

【問題背景】

近來,一種新的傳染病肆虐全球。蓬萊國也發現了零星感染者,為防止該病在蓬萊國大範圍流行,該國** 決定不惜一切代價控制傳染病的蔓延。不幸的是,由於人們尚未完全認識這種傳染病,難以準確判別病毒攜帶者,更沒有研製出疫苗以保護易感人群。於是,蓬萊國 的疾病控制中心決定採取切斷傳播途徑的方法控制疾病傳播。經過 who (世界衛生組織)以及全球各國科研部門的努力,這種新興傳染病的傳播途徑和控制方法已經研究消除,剩下的任務就是由你協助蓬萊國疾控中心制定乙個有效的控 制辦法。

【問題描述】

研究表明,這種傳染病的傳播具有兩種很特殊的性質;第一是它的 傳播途徑是樹型的,乙個人 x 只可能被某個特定的人 y 感染,只要 y 不得病,或者是 xy 之間的傳播途徑被切斷,則 x 就不會得病。第二是,這種疾病的傳播有週期性,在乙個疾病傳播週期之內,傳染病將只會感染一代患者,而不會再傳播給下一代。

這 些性質大大減輕了蓬萊國疾病防控的壓力,並且他們已經得到了國內部分易感人群的潛在傳播途徑圖(一棵樹)。但是,麻煩還沒有結束。由於蓬萊國疾控中心人手 不夠,同時也缺乏強大的技術,以致他們在乙個疾病傳播週期內,只能設法切斷一條傳播途徑,而沒有被控制的傳播途徑就會引起更多的易感人群被感染(也就是與 當前已經被感染的人有傳播途徑相連,且連線途徑沒有被切斷的人群)。當不可能有健康人被感染時,疾病就中止傳播。所以,蓬萊國疾控中心要制定出乙個切斷傳 播途徑的順序,以使盡量少的人被感染。

你的程式要針對給定的樹,找出合適的切斷順序。

【輸入格式】

輸入格式的第一行是兩個整數 n ( 1≤n≤300 )和 p 。接下來 p 行,每一行有兩個整數 i 和 j ,表示節點 i 和 j 間有邊相連(意即,第 i 人和第 j 人之間有傳播途徑相連)。其中節點1 是已經被感染的患者。

【輸出格式】

只有一行,輸出總共被感染的人數。

【輸入樣例】

7 61 2

1 32 4

2 53 6

3 7【輸出樣例】

【題解】

想到了dp,但是每個子樹切斷幾次,什麼時候切斷,可能先切斷一次過幾次再切斷,所以很難分狀態

然後搜尋?

然而搜尋感染多少人並不好實現

所以我突然想到了可以倒著求解

切斷乙個結點上面的那條路就能把這條結點以及子樹上的結點全部保護

所以我們可以求出最多能保護多少個結點

先建樹

然後用sum陣列儲存每個結點的子樹和

m為最深的層數

然後還有儲存每一層的結點是哪些

f[i]表示i結點上面的那條邊是不是被切斷了

然後把根節點1作為第一層

從第二層開始搜尋

切斷第i個結點就把f[i]改為true(i結點位於該層)

然而一開始我的想法是如果搜尋到這個節點,這個節點的父節點如果f為true那麼它的f也變成true

但是我發現這樣很難回溯

所以就增加乙個類似並查集的find函式

如果它到樹根的路上有f為true的點

說明當前狀態下它已經被保護了,就跳過它

然後沒有被保護的結點就保護住

再搜尋下一層

搜到第m+1層就退出

記住一定要邊搜尋邊更新最優答案因為可能搜不到最後一層所有的結點就都被保護了(比如一條鏈)

最後的答案即為結點數-最大能保護的節點數

資料小也不用優化想怎麼浪怎麼浪

1 #include2 #include3 #include4 #include5

#define maxn 305

6using

namespace

std;

7int

read()

10while(ch>='

0'&&ch<='9')

11return x*f;12}

13int

n,p,m,a[maxn][maxn],b[maxn][maxn],fa[maxn],dep[maxn],num[maxn],sum[maxn],maxx;

14bool

f[maxn];

15bool find(int

x)20

void build_tree(int x,int

depth)32}

33void dfs(int depth,int

ans)44}

45int

main()

54 build_tree(1,1

);55 dfs(2,0

);56 printf("

%d",n-maxx);

57return0;

58 }

NOIP2003 傳染病控制

純搜尋題 一開始思路比較混亂,但是仔細想想便能得出正解。我們預處理出每一棵子樹的大小 每一層的兒子們,之後進行一次dfs,暴力列舉刪除每一棵子樹,同時更新答案,同時注意標記是否刪除。搜尋完成後回溯。最終就能得出答案。1 include 2 using namespace std 3int n,m,a...

NOIP 2003傳染病控制

思路 1.dfs一遍,求出每個點的size,fa,deep 2.按照deep將每個點存入vector中 3.按照deep進行dffs求解答案 dffs時切斷某個點與fa的連線表示該點打上標記,表示不被感染,並減去該點size,每次進入下一層時,掃fa,如果fa被標記,則該點也被標記。最後dffs結束...

noip2003傳染病控制 2008 11 5

noip2003傳染病控制 2008.11.5 小結 1.這道題,我的方法普遍的要快很多,以空間換時間,我先把他們的關係用不同的陣列存起來,包括每個人的前面,每個人的後面,都存了下來,算是對資料的初始化吧。包括每個人在第幾層,然後一層一層的直接呼叫。好的資料結構真的很重要,載運算前,對資料的處理,真...