描述
研究表明,这种传染病的传播具有两种很特殊的性质;
第一是它的传播途径是树型的,一个人X只可能被某个特定的人Y感染,只要Y不
得病,或者是XY之间的传播途径被切断,则X就不会得病。
第二是,这种疾病的传播有周期性,在一个疾病传播周期之内,传染病将只会感染一
代患者,而不会再传播给下一代。
这些性质大大减轻了蓬莱国疾病防控的压力,并且他们已经得到了国内部分易感人群
的潜在传播途径图(一棵树)。但是,麻烦还没有结束。由于蓬莱国疾控中心人手不够,同时也缺乏强大的技术,以致他们在一个疾病传播周期内,只能设法切断一条传播途径,而没有被控制的传播途径就会引起更多的易感人群被感染(也就是与当前已经被感染的人有传播途径相连,且连接途径没有被切断的人群)。当不可能有健康人被感染时,疾病就中止传播。所以,蓬莱国疾控中心要制定出一个切断传播途径的顺序,以使尽量少的人被感染。你的程序要针对给定的树,找出合适的切断顺序。
格式
输入格式
输入格式的第一行是两个整数n(1≤n≤300)和p。接下来p行,每一行有两个整数i
和j,表示节点i和j间有边相连(意即,第i人和第j人之间有传播途径相连)。其中节点
1是已经被感染的患者。
输出格式
只有一行,输出总共被感染的人数。
改了好久才AC,代码有点乱(很值得好好琢磨的一道题)
#include<iostream> #include<vector> #include<cstring> using namespace std; struct edge{ int f,t; }; +; int n,p,node[maxn],flag[maxn],ans=maxn,cs; vector<edge> b[maxn]; vector<int> GG[maxn]; vector<int> G[maxn]; int calcsize(int x){ node[x]=; ) return node[x]; ;i<G[x].size();i++) node[x]+=calcsize(G[x][i]); return node[x]; } void dfs1(int n,int f){ ){ return; } ;i<G[f].size();i++){ b[n].push_back((edge){f,G[f][i]}); dfs1(n+,G[f][i]); } } void vis(int x){ flag[x]=; ;i<G[x].size();i++) vis(G[x][i]); } void disvis(int x){ flag[x]=; ;i<G[x].size();i++) disvis(G[x][i]); } void dfs(int n,int now){ ans=min(ans,now); if(n>cs){ return; } ;i<b[n].size();i++){ edge &e=b[n][i]; if(!flag[e.f]){ vis(e.t);dfs(n+,now-node[e.t]); disvis(e.t); } } } void bulid(int u,int fa){ int d=GG[u].size(); ;i<d;i++){ int v=GG[u][i]; if(v!=fa){ G[u].push_back(v); bulid(v,u); } } } int main() { int i,j; cin>>n>>p; ;k<p;k++){ cin>>i>>j;GG[i].push_back(j);GG[j].push_back(i); } memset(flag,,sizeof(flag)); bulid(,-);calcsize();dfs1(,); ;i<=maxn;i++){ ){ cs=i-;break; } }dfs(,n);cout<<ans; ; }