P1041 传染病控制——暴力遍历所有相同深度的节点

P1041 传染病控制

说实话这种暴力我还是头一次见,每次病毒都会往下传染一层;

数据范围小,我们可以直接枚举当前层保护谁就好了;

用vector 记录相同层数的节点;维护已经断了的点;

如果超出最底层或者都已经被保护就更新答案;

#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn=1010;
vector<int> v[maxn];
int pre[maxn],last[maxn],other[maxn],l;

void add(int x,int y)
{
    l++;
    pre[l]=last[x];
    last[x]=l;
    other[l]=y;
}

int n,m;

int siz[maxn],dep[maxn];

int father[maxn];

int madep;
void dfs1(int x,int fa)
{
    siz[x]=1;
    dep[x]=dep[fa]+1;
    father[x]=fa;
    madep=max(madep,dep[x]);
    for(int p=last[x];p;p=pre[p])
    {
        int v=other[p];
        if(v==fa) continue;
        dfs1(v,x);
        siz[x]+=siz[v];
    }
}

int vis[maxn];

int ans;

void dfs(int x,int sum)
{
    if(x==madep+1)
    {
        ans=min(ans,sum);
        return ;
    }
    bool flag=0;
    for(int i=0;i<v[x].size();i++)
    {
        if(vis[father[v[x][i]]])//chosen not ill
        {
            vis[v[x][i]]=1;
        }
        else {
        vis[v[x][i]]=0;
        flag=1;
        }
    }
    if(!flag)
    {
        ans=min(ans,sum);
        return ;
    }

    for(int i=0;i<v[x].size();i++)
    {
        int u=v[x][i];
        if(vis[u]) continue;
        vis[u]=1;
        dfs(x+1,sum-siz[u]);
        vis[u]=0;
    }
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        add(x,y);
        add(y,x);
    }
    dfs1(1,0);
    for(int i=1;i<=n;i++)
    {
        v[dep[i]].push_back(i);
    }
    ans=n;
    dfs(2,n);
    printf("%d",ans);
    return 0;
}

原文地址:https://www.cnblogs.com/WHFF521/p/11746620.html

时间: 2024-10-28 15:29:53

P1041 传染病控制——暴力遍历所有相同深度的节点的相关文章

P1041 传染病控制

P1041 传染病控制 题目背景 近来,一种新的传染病肆虐全球.蓬莱国也发现了零星感染者,为防止该病在蓬莱国大范围流行,该国政府决定不惜一切代价控制传染病的蔓延.不幸的是,由于人们尚未完全认识这种传染病,难以准确判别病毒携带者,更没有研制出疫苗以保护易感人群.于是,蓬莱国的疾病控制中心决定采取切断传播途径的方法控制疾病传播.经过 WHO(世界卫生组织)以及全球各国科研部门的努力,这种新兴传染病的传播途径和控制方法已经研究清楚,剩下的任务就是由你协助蓬莱国疾控中心制定一个有效的控制办法. 题目描述

洛谷 P1041 传染病控制

P1041 传染病控制 dfs枚举去掉的子树,更新当前感染节点 emmmm 这个题,每次去掉最大的子树的做法是错误的 比如 hhh,按照那个贪心的思路肯定是先去掉左边的子树,这样答案会是4 但是先去掉右边的子树的话答案就是3 1 #include<bits/stdc++.h> 2 using namespace std; 3 #define maxn 1000000+15 4 int n,m,x,y,fa[maxn],mmp[10000],sum[maxn],ans=1; 5 vector&l

二叉树的层次遍历和其深度

//二叉树的层次遍历和其深度#include <cstdio>#include <cstdlib>//define _OJ_#define maxsize 100typedef struct tree1{    char data;    struct tree1 *lchild;    struct tree1 *rchild;} tree1, *tree; typedef struct queue1{    tree data;    struct queue1 *next;}

P1041 传染病控制(dfs)

P1041 传染病控制 题目背景 近来,一种新的传染病肆虐全球.蓬莱国也发现了零星感染者,为防止该病在蓬莱国大范围流行,该国政府决定不惜一切代价控制传染病的蔓延.不幸的是,由于人们尚未完全认识这种传染病,难以准确判别病毒携带者,更没有研制出疫苗以保护易感人群.于是,蓬莱国的疾病控制中心决定采取切断传播途径的方法控制疾病传播.经过 WHOWHO(世界卫生组织)以及全球各国科研部门的努力,这种新兴传染病的传播途径和控制方法已经研究清楚,剩下的任务就是由你协助蓬莱国疾控中心制定一个有效的控制办法. 题

二叉树递归与非递归遍历,最近公共父节点算法

#include <iostream> #include <stack> using namespace std; #define MAX 100 //字符串最大长度 typedef struct Node //二叉树结点 { char data; Node *lchild,*rchild; } *Btree; void createBT(Btree &t); //先序构造二叉树 void preorder(Btree &t); //二叉树递归先序遍历 void i

2.遍历XML即添加修改节点

1.xml <?xml version="1.0" encoding="utf-8" ?> <stories> <story ac="98"> <title>A House in Aungier Street</title> <author> <name>Sheridan le Fanu</name> <nationality>Irish&

二叉树的建立、四种遍历、求深度、求叶子结点数

1 #include<stdio.h> 2 #include<stdlib.h> 3 typedef struct Node{ 4 struct Node *lchild, *rchild; 5 char data; 6 }BiNode, *BiTree; 7 BiTree CreatBiTree(BiTree *T)//前序建树,输入的是扩展二叉树 8 { 9 char a; 10 scanf("%c", &a); 11 if(a == '#') *T

Java实现二叉树地遍历、求深度和叶子结点的个数

一.分析 二叉树是n个结点所构成的集合,它或为空树,或为非空树.对于非空树,它有且仅有一个根结点,且除根结点以外的其余结点分为两个互不相交的子集,分别称为左子树和右子树,它们本身又都是二叉树. 显而易见,二叉树具有递归的性质,因此表示二叉树的结点至少要包含3个域:数据域.左指针.右指针.在Java中,我们可以将二叉树的结点视为一个类,其中含有左子树地址.右子树地址和数据三个属性,每个结点即使类的实例化对象.因为二叉树的递归性质,所以我们可以通过递归来实现二叉树地求深度.求叶子结点的个数.先序.中

[NOIP2003] 提高组 洛谷P1041 传染病控制

题目背景 近来,一种新的传染病肆虐全球.蓬莱国也发现了零星感染者,为防止该病在蓬莱国大范围流行,该国政府决定不惜一切代价控制传染病的蔓延.不幸的是,由于人们尚未完全认识这种传染病,难以准确判别病毒携带者,更没有研制出疫苗以保护易感人群.于是,蓬莱国的疾病控制中心决定采取切断传播途径的方法控制疾病传播.经过 WHO(世界卫生组织)以及全球各国科研部门的努力,这种新兴传染病的传播途径和控制方法已经研究清楚,剩下的任务就是由你协助蓬莱国疾控中心制定一个有效的控制办法. 题目描述 研究表明,这种传染病的