1. 程式人生 > >luogu cogs . [NOIP2003] 傳染病控制 WA(1/2)

luogu cogs . [NOIP2003] 傳染病控制 WA(1/2)

getch 特定 start using def algo logs space blog

★★★ 輸入文件:epidemic.in 輸出文件:epidemic.out 簡單對比
時間限制:1 s 內存限制:128 MB

【問題背景】

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

【問題描述】

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

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

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

【輸入格式】

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

【輸出格式】

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

【輸入樣例】

7 6
1 2
1 3
2 4
2 5
3 6
3 7

【輸出樣例】

3

正解是dfs,而用bfs過5點:

#include<iostream>
#include<cstdio>
#include
<algorithm> #include<cmath> #include<queue> #include<vector> using namespace std; const int N=101000; int answer; int deep[N]; vector<int> DE[N]; int point,road; int val[N]; int Max_deep; queue<int>q; bool vis[N]; int son[N]; int head[N]; int now=1; struct node{ int u,v,nxt; }E[N]; inline void add(int u,int v) { E[now].v=v; E[now].nxt=head[u]; head[u]=now++; } inline int read() { int x=0;char c=getchar(); while(c<0||c>9)c=getchar(); while(c>=0&&c<=9)x=x*10+c-0,c=getchar(); return x; } void make_deep() { q.push(1); deep[1]=1; DE[1].push_back(1); while(!q.empty()) { int top=q.front(); q.pop(); for(int i=head[top];i!=-1;i=E[i].nxt) { q.push(E[i].v); deep[E[i].v]=deep[top]+1; DE[deep[E[i].v]].push_back(E[i].v); Max_deep=max(Max_deep,deep[E[i].v]); } } } void make_val() { for(int Q=Max_deep;Q>=1;Q--) { for(int i=0;i<DE[Q].size();i++) { int my=DE[Q].size(); int tt=DE[Q][i]; if(son[tt]==0) val[tt]=1; else { for(int j=head[tt];j!=-1;j=E[j].nxt) val[tt]+=val[E[j].v]; val[tt]++; } } } } inline void change(int start) { q.push(start); while(!q.empty()) { int top=q.front(); q.pop(); vis[top]=1; for(int i=head[top];i!=-1;i=E[i].nxt) q.push(E[i].v); } } inline void find_biggestandwork(int line) { int maxn=-1,maxk; for(int i=0;i<DE[line].size();i++) { int tt=DE[line][i]; if(val[tt]>maxn&&!vis[tt]) { maxn=val[tt]; maxk=tt; } } vis[maxk]=1; answer-=maxn; change(maxk); } inline void work() { int Q=Max_deep; for(int i=2;i<=Q;i++) find_biggestandwork(i); } int main() { freopen("epidemic.in","r",stdin); freopen("epidemic.out","w",stdout); point=read(); road=read(); answer=point; for(int i=1;i<=point;i++) head[i]=-1; for(int i=1;i<=road;i++) { int u=read(); int v=read(); son[max(u,v)]++; add(min(u,v),max(u,v)); } make_deep(); make_val(); work(); printf("%d",answer); return 0; } /* 7 6 1 2 1 3 2 4 2 5 3 6 3 7 3 */

luogu cogs . [NOIP2003] 傳染病控制 WA(1/2)