zoukankan      html  css  js  c++  java
  • [NOIP2003] 传染病控制

    看到数据范围这么小可以发现它就是一个搜索题啦qwq~~
    (有树形DP的解法吗??有嘛??)

    有一个很显然的策略就是到第(i)层的时候,切断一个第(i)层和第(i+1)层的边是局部最优,也是全局最优。

    所以说。。。看起来是bfs套dfs了???(逃)

    既然是搜索题,那么肯定是我们要从每层之间枚举一条边封锁掉它,然后继续搜索。但是在搜索的时候处理每层的情况不太好处理,所以我们考虑预处理出每个节点和根节点相距的距离,把每一层(就是距离根节点距离相等)的点放在一起。

    搜索就是传递两个值,一个是层数,一个是当前的答案值。没有什么优秀的剪枝,就是很普通的:

    • 当前答案比到现在为止记录下来最优的答案大的话,return。
    • 当前层所有的节点都不会被感染,return。

    在代码实现的过程中为了方便,我写了两个函数:

    • (calc())函数:计算当前层还有多少会被传染的节点
    • (tag())函数:将now的子树和now都打上标记(1是不会被传染了,0是还有可能被传染)

    以下是代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define MAXN 500
    using namespace std;
    int n,m,maxx,edge_number,ans=2147483647;
    int len[MAXN],head[MAXN],done[MAXN],f[MAXN],vec[MAXN][MAXN],cnt[MAXN];
    struct Edge{int nxt,to;}edge[MAXN<<1];
    inline 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;
    }
    inline void add(int from,int to)
    {
    	edge[++edge_number].nxt=head[from];
    	edge[edge_number].to=to;
    	head[from]=edge_number;
    }
    inline void dfs(int now,int fa)
    {
    	for(int i=head[now];i;i=edge[i].nxt)
    	{
    		int v=edge[i].to;
    		if(v==fa) continue;
    		len[v]=len[now]+1;
    		f[v]=now;
    		maxx=max(maxx,len[v]);
    		dfs(v,now);
    	}
    }
    inline void tag(int now,int color)
    {
    	done[now]=color;
    	for(int i=head[now];i;i=edge[i].nxt)
    	{
    		int v=edge[i].to;
    		if(v==f[now]) continue;
    		done[v]=color;
    		tag(v,color);
    	}
    }
    inline int calc(int dep)
    {
    	int sum=0;
    	for(int i=1;i<=cnt[dep];i++)
    		if(done[vec[dep][i]]==0)
    			sum++;
    	return sum;
    }
    inline void search(int dep,int sum)
    {
    	if(sum>=ans) return;
    	if(dep>maxx||calc(dep)==0)
    	{
    		ans=min(ans,sum);
    		return;
    	}
    	for(int i=1;i<=cnt[dep];i++)
    	{
    		int to=vec[dep][i];
    		if(done[to]==1) continue;
    		tag(to,1);
    		search(dep+1,sum+calc(dep));
    		tag(to,0);
    	}
    }
    int main()
    {
    	n=read(),m=read();
    	for(int i=1;i<=m;i++)
    	{
    		int u,v;
    		u=read(),v=read();
    		add(u,v);
    		add(v,u);
    	}
    	dfs(1,0);
    	for(int i=1;i<=n;i++)
    		vec[len[i]][++cnt[len[i]]]=i;
    	search(1,1);
    	printf("%d
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    HDU 1358 Period (KMP)
    POJ 1042 Gone Fishing
    Csharp,Javascript 获取显示器的大小的几种方式
    css text 自动换行的实现方法 Internet Explorer,Firefox,Opera,Safar
    Dynamic Fonts动态设置字体大小存入Cookie
    CSS Image Rollovers翻转效果Image Sprites图片精灵
    CSS three column layout
    css 自定义字体 Internet Explorer,Firefox,Opera,Safari
    颜色选择器 Color Picker,Internet Explorer,Firefox,Opera,Safar
    CSS TextShadow in Safari, Opera, Firefox and more
  • 原文地址:https://www.cnblogs.com/fengxunling/p/9846411.html
Copyright © 2011-2022 走看看