【问题背景】
大范围流行,该国政府决定不惜一切代价控制传染病的蔓延。不幸的是,由于人们尚未完
全认识这种传染病,难以准确判别病毒携带者,更没有研制出疫苗以保护易感人群。于是,
蓬莱国的疾病控制中心决定采取切断传播途径的方法控制疾病传播。经过 WHO(世界卫
生组织)以及全球各国科研部门的努力,这种新兴传染病的传播途径和控制方法已经研究
消楚,剩下的任务就是由你协助蓬莱国疾控中心制定一个有效的控制办法。
得病,或者是XY之间的传播途径被切断,则X就不会得病。
代患者,而不会再传播给下一代。
的潜在传播途径图(一棵树)。但是,麻烦还没有结束。由于蓬莱国疾控中心人手不够,同
时也缺乏强大的技术,以致他们在一个疾病传播周期内,只能设法切断一条传播途径,而
没有被控制的传播途径就会引起更多的易感人群被感染(也就是与当前已经被感染的人有
传播途径相连,且连接途径没有被切断的人群)。当不可能有健康人被感染时,疾病就中止
传播。所以,蓬莱国疾控中心要制定出一个切断传播途径的顺序,以使尽量少的人被感染。
你的程序要针对给定的树,找出合适的切断顺序。
【输入格式】
和j,表示节点i和j间有边相连(意即,第i人和第j人之间有传播途径相连)。其中节点
1是已经被感染的患者。
【输出格式】
解题思路:这题一开始想的是贪心,,不过好像有后效性,会找到反例。。正确的解法是搜索,如题意我们要做的就是每一层剪掉一条边,所以只要回溯搜索每一层剪掉的边就可以了。可以加上最优性剪枝减少一些时间:若当前感染人数已经超过当前更新到的最大答案,显然不需要再往下搜了。
代码:
#include
#include
#include
using namespace std;
struct point{
int e;
point *next;
};
point *a[305]={0},*pp,*p1;
int que[305],u[305]={0},i,n,p,minans,len,e,s;
void dfs(int k,int que[],int len,int now)
{if (now+len-1>=minans) return;
//cout<<len<<endl;
if (len==0) {if (now
if (now>=minans) return;
int i,que1[305],len1=0;
point *p;
p=(point*)malloc(sizeof(point));
for (i=1;i<=len;i++)
if (i!=k) {p=a[que[i]];
while (p!=0){len1++;que1[len1]=p->e;p=p->next;}
}
//printf("%d*\n",len1);
if (len1==0) {if (now+len-1
for (i=1;i<=len1;i++)
dfs(i,que1,len1,now+len-1);
}
int main(){
freopen("bin.txt","r",stdin);
scanf("%d%d",&n,&p);
u[1]=1;
for (i=1;i<=p;i++)
{scanf("%d%d",&s,&e);
if (u[e]==1) swap(s,e);
pp=(point*)malloc(sizeof(point));
pp->e=e;
pp->next=a[s];
a[s]=pp;
u[e]=1;
}
p1=(point*)malloc(sizeof(point));
p1=a[1];minans=1111111;
while (p1!=0) {len++;que[len]=p1->e;p1=p1->next;}
for (i=1;i<=len;i++)
dfs(i,que,len,1);
printf("%d",minans);
fclose(stdin);
}