标签:
研究表明,这种传染病的传播具有两种很特殊的性质;
第一是它的传播途径是树型的,一个人X只可能被某个特定的人Y感染,只要Y不
得病,或者是XY之间的传播途径被切断,则X就不会得病。
第二是,这种疾病的传播有周期性,在一个疾病传播周期之内,传染病将只会感染一
代患者,而不会再传播给下一代。
这些性质大大减轻了蓬莱国疾病防控的压力,并且他们已经得到了国内部分易感人群
的潜在传播途径图(一棵树)。但是,麻烦还没有结束。由于蓬莱国疾控中心人手不够,同时也缺乏强大的技术,以致他们在一个疾病传播周期内,只能设法切断一条传播途径,而没有被控制的传播途径就会引起更多的易感人群被感染(也就是与当前已经被感染的人有传播途径相连,且连接途径没有被切断的人群)。当不可能有健康人被感染时,疾病就中止传播。所以,蓬莱国疾控中心要制定出一个切断传播途径的顺序,以使尽量少的人被感染。你的程序要针对给定的树,找出合适的切断顺序。
输入格式的第一行是两个整数n(1≤n≤300)和p。接下来p行,每一行有两个整数i
和j,表示节点i和j间有边相连(意即,第i人和第j人之间有传播途径相连)。其中节点
1是已经被感染的患者。
只有一行,输出总共被感染的人数。
1 #include<iostream> 2 #include<vector> 3 #include<cstring> 4 using namespace std; 5 struct edge{ 6 int f,t; 7 }; 8 const int maxn=300+10; 9 int n,p,node[maxn],flag[maxn],ans=maxn,cs; 10 vector<edge> b[maxn]; 11 vector<int> GG[maxn]; 12 vector<int> G[maxn]; 13 int calcsize(int x){ 14 node[x]=1; 15 if(G[x].size()==0) return node[x]; 16 for(int i=0;i<G[x].size();i++) node[x]+=calcsize(G[x][i]); 17 return node[x]; 18 } 19 void dfs1(int n,int f){ 20 if(G[f].size()==0){ 21 return; 22 } 23 for(int i=0;i<G[f].size();i++){ 24 b[n].push_back((edge){f,G[f][i]}); 25 dfs1(n+1,G[f][i]); 26 } 27 } 28 void vis(int x){ 29 flag[x]=1; 30 for(int i=0;i<G[x].size();i++) vis(G[x][i]); 31 } 32 void disvis(int x){ 33 flag[x]=0; 34 for(int i=0;i<G[x].size();i++) disvis(G[x][i]); 35 } 36 void dfs(int n,int now){ 37 ans=min(ans,now); 38 if(n>cs){ 39 return; 40 } 41 for(int i=0;i<b[n].size();i++){ 42 edge &e=b[n][i]; 43 if(!flag[e.f]){ 44 vis(e.t);dfs(n+1,now-node[e.t]); 45 disvis(e.t); 46 } 47 } 48 49 } 50 void bulid(int u,int fa){ 51 int d=GG[u].size(); 52 for(int i=0;i<d;i++){ 53 int v=GG[u][i]; 54 if(v!=fa){ 55 G[u].push_back(v); 56 bulid(v,u); 57 } 58 } 59 } 60 int main() 61 { 62 int i,j; 63 cin>>n>>p; 64 for(int k=0;k<p;k++){ 65 cin>>i>>j;GG[i].push_back(j);GG[j].push_back(i); 66 } 67 memset(flag,0,sizeof(flag)); 68 bulid(1,-1);calcsize(1);dfs1(1,1); 69 for(int i=1;i<=maxn;i++){ 70 if(b[i].size()==0){ 71 cs=i-1;break; 72 } 73 }dfs(1,n);cout<<ans; 74 return 0; 75 }
标签:
原文地址:http://www.cnblogs.com/gzhonghui/p/5699765.html