zoukankan      html  css  js  c++  java
  • Luogu 1041 传染病控制

    题目链接:https://www.luogu.org/problemnew/show/P1041

    思路:

    让感染的人数最少,即让不被感染的人数最大。

    那么有一个贪心策略即为先搜索子树大小大的,搭配一个最优性剪枝使用更佳。

    朴素做法就是按深度由小到大去枚举断边后的情况,在这其中即可统计最大值。

    记得回溯。

    代码:

    #include <cstdio>
    #include <cctype>
    #include <cstring>
    #include <iostream>
    #include <vector>
    #include <algorithm>
    const int INF=1<<30;
    const int MAXN=10050;
    using namespace std;
    vector<int> g[MAXN],w[MAXN];
    int n,p,u,v,cnt,num,dep[MAXN],sonnum[MAXN];
    bool tag[MAXN];
    void update(int x,bool s){
        tag[x]=s;
        for(int i=0;i<(int)g[x].size();i++){
            tag[g[x][i]]=s;
            update(g[x][i],s);
        }
    }
    void dfs1(int x){
        sonnum[x]=1; 
        for(int i=0;i<(int)g[x].size();i++){
            int to=g[x][i];
            dep[to]=dep[x]+1;
            dfs1(to);
            sonnum[x]+=sonnum[to];
        }
    }
    void dfs2(int x){
        if((int)w[x].size()==0) return ;
        for(int i=0;i<(int)w[x].size();i++){
            int to=w[x][i];
            if(tag[to]) continue;
            cnt+=sonnum[to];
            num=max(num,cnt);
            update(to,true);
            dfs2(x+1);
            update(to,false);
            cnt-=sonnum[to];
        }
    }
    int main(){
        ios::sync_with_stdio(false);
        cin>>n>>p;
        for(int i=1;i<=p;i++){
            cin>>u>>v;
            if(u>v) swap(u,v);//由于并没有建双向边,那就得按照一个顺序来建树
            g[u].push_back(v);
        }
        dfs1(1);
        for(int i=1;i<=n;i++) w[dep[i]].push_back(i); 
        dfs2(1);
        printf("%d
    ",n-num);
        return 0;
    }
  • 相关阅读:
    hdu 4460spfa用map来实现
    hdu 2579
    hdu 2845
    hdu 4462
    hdu 4557
    hdu 4639
    URAL 2078 Bowling game
    UVA
    HDU 5773 The All-purpose Zero 脑洞LIS
    Codeforces Round #368 (Div. 2) C. Pythagorean Triples 数学
  • 原文地址:https://www.cnblogs.com/BeyondLimits/p/11134412.html
Copyright © 2011-2022 走看看