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

luogu P1041 傳染病控制

struct 任務 code lag 個人 表示 fff == 部門

題目背景

近來,一種新的傳染病肆虐全球。蓬萊國也發現了零星感染者,為防止該病在蓬萊國大範圍流行,該國政府決定不惜一切代價控制傳染病的蔓延。不幸的是,由於人們尚未完全認識這種傳染病,難以準確判別病毒攜帶者,更沒有研制出疫苗以保護易感人群。於是,蓬萊國的疾病控制中心決定采取切斷傳播途徑的方法控制疾病傳播。經過 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:

補一個暴力題解dfs+回溯+剪紙
#include<cstdio>
#include<iostream>
using namespace
std; #define N 90000 int read(){ int x=0,f=1;char ch=getchar(); while(ch<0 || ch>9){if(ch==-)f=-1;ch=getchar();} while(ch>=0 && ch<=9){x=x*10+ch-0;ch=getchar();} return x*f; } int n,m; struct node{ int v,next; }edge[N]; int head[N];int dep[N];bool ill[N];int num; void add_edge(int x,int y){ edge[++num].v=y;edge[num].next=head[x];head[x]=num; } void find_deep(int x) { for(int i=head[x];i;i=edge[i].next) { int v=edge[i].v; dep[v]=dep[x]+1; find_deep(v); } return; } int ans = 0x7fffffff; void dfs(int deep,int cnt) { if(cnt>=ans)return ; bool flag=0; for(int i=1;i<=n;i++)//向深層傳染 if(dep[i]==deep&&ill[i]) { for(int j=head[i];j;j=edge[j].next) { int v=edge[j].v; ill[v]=1; ++cnt; flag=1; } } --cnt; for(int i=1;i<=n;i++) { if(dep[i]==deep+1 && ill[i]) { ill[i]=0; dfs(deep+1,cnt); ill[i]=1; } } ++cnt; for(int i=1;i<=n;i++) if(dep[i]==deep&&ill[i]) { for(int j=head[i];j;j=edge[j].next) { int v=edge[j].v; ill[v]=0; --cnt; } } if(!flag) { ans=min(ans,cnt); return; } } int main() { n=read();m=read(); int u,v; for(int i=1;i<=m;i++){ u=read(); v=read(); if(u<v) add_edge(u,v); else add_edge(v,u); } dep[1]=1; find_deep(1); ill[1]=1; dfs(1,1); printf("%d\n",ans); return 0; }

luogu P1041 傳染病控制