1. 程式人生 > >洛谷 P1041 傳染病控制

洛谷 P1041 傳染病控制

clu names 可能 def void .org https 保存 ++

P1041 傳染病控制

題目背景

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

題目描述

研究表明,這種傳染病的傳播具有兩種很特殊的性質;

第一是它的傳播途徑是樹型的,一個人X只可能被某個特定的人Y感染,只要Y不得病,或者是XY之間的傳播途徑被切斷,則X就不會得病。

第二是,這種疾病的傳播有周期性,在一個疾病傳播周期之內,傳染病將只會感染一代患者,而不會再傳播給下一代。

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

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

輸入輸出格式

輸入格式:

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

輸出格式:

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

輸入輸出樣例

輸入樣例#1: 復制
7 6
1 2
1 3
2 4
2 5
3 6
3 7
輸出樣例#1: 復制

/*
    切斷一個結點上面的那條路就能把這條結點以及子樹上的結點全部保護 所以我們可以求出最多能保護多少個結點 
    然後用sum數組存儲每個結點的子樹和 m為最深的層數 然後還有保存每一層的結點是哪些 f[i]表示i結點上面的那條邊是不是被切斷了 然後把根節點1作為第一層 從第二層開始搜索 切斷第i個結點就把f[i]改為true
    增加一個神似並茶幾的find找爹函數 如果它到樹根的路上有f為true的點 說明當前狀態下它已經被保護了,就跳過它 然後沒有被保護的結點就保護住再搜索下一層 
*/ #include<vector> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define maxn 501 using namespace std; vector<int>a[maxn]; int n,m,p,mx,num; int map[maxn][maxn]; int f[maxn],head[maxn]; int sz[maxn],dep[maxn],fa[maxn]; struct node{int to,pre;}e[maxn*2]; void Insert(int from,int to){ e[++num].to=to;e[num].pre=head[from];head[from]=num; } bool find(int x){ if(x==1) return false; if(f[x]) return true; return find(fa[x]); } void build(int now,int father){ dep[now]=dep[father]+1; fa[now]=father; a[dep[now]].push_back(now); m=max(m,dep[now]); sz[now]=1; for(int i=head[now];i;i=e[i].pre){ int to=e[i].to; if(to==father) continue; build(to,now); sz[now]+=sz[to]; } } void dfs(int depth,int ans){ if(depth==m+1) return; int n1=a[depth].size(),x; for(int i=0;i<n1;i++){ x=a[depth][i]; if(find(x)) continue; f[x]=1; mx=max(mx,ans+sz[x]); dfs(depth+1,ans+sz[x]); f[x]=0; } } int main(){ scanf("%d%d",&n,&p); int x,y; for(int i=1;i<=p;i++){ scanf("%d%d",&x,&y); Insert(x,y),Insert(y,x); } build(1,1); dfs(2,0); printf("%d",n-mx); }

 

洛谷 P1041 傳染病控制