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

    题目地址

    题目链接

    题解

    这里讲一个非正解——贪心+随机化
    贪心的想法是什么?
    我们dfs一遍处理出每个节点子树内的节点数量,记为(siz)
    贪心的砍掉(siz)最大的那个子树,在树的形态比较正常的情况下是可以得到最优解的。
    如何hack掉这种贪心?
    构造一条链,在中间的地方放一个“很胖”的分支,可以只分两层,每层的节点构造多一些(注意要使这个分支的节点数量小于链下半部分的节点数量)
    这样子我们按照上述贪心,将会得到错误的结果,更优的做法是把这个分支直接砍掉(因为链上每次传染只会增加一个被传染的人)
    当然,实际构造可以更加复杂,这只是最极端的情况。
    不过,这种错误的贪心已经可以得到90分了。
    如何得到满分?
    要对答案产生影响,那么需要的那个分支的大小就不会太小(因为实际情况下一般是不会像上面那样子构造的,毒瘤出题人除外
    我们采用随机化的思想(实际上下面这个随机化的方法并不好,不过数据水也就水过去了)。
    我们定义一种判定规则,如果某个节点恰好符合这个判定规则(一般是随机的),那么就改变原本的贪心策略,换用另外一个策略。
    这里用的判定规则是rand出来的结果对233取模是否为0.
    如果符合这个判定规则的话,我们就选择子树大小第二大(这个使用优先队列实现)的子树砍掉。
    当然,这很不靠谱。
    通常的做法是在不TLE的情况下尽量跑多次(能多少次就多少次),对所有结果取min。
    所以随机化能水过去一般靠大量的尝试,尽量靠谱的判定规则,以及另外一个策略靠不靠谱。。。
    注意,在此题中,需要使判定成功的可能性尽可能低,当然也不能太低
    下面给出代码,注意,因为代码里只跑了200次进行尝试,不保证一定能ac,可以自行调大次数,或者多交几次(我交了2发才过)。

    #include <bits/stdc++.h>
    
    #define ll long long
    #define inf 0x3f3f3f3f
    #define il inline
    
    namespace io {
    
        #define in(a) a=read()
        #define out(a) write(a)
        #define outn(a) out(a),putchar('
    ')
    
        #define I_int ll
        inline I_int read() {
            I_int x = 0 , f = 1 ; char c = getchar() ;
            while( c < '0' || c > '9' ) { if( c == '-' ) f = -1 ; c = getchar() ; }
            while( c >= '0' && c <= '9' ) { x = x * 10 + c - '0' ; c = getchar() ; }
            return x * f ;
        }
        char F[ 200 ] ;
        inline void write( I_int x ) {
            if( x == 0 ) { putchar( '0' ) ; return ; }
            I_int tmp = x > 0 ? x : -x ;
            if( x < 0 ) putchar( '-' ) ;
            int cnt = 0 ;
            while( tmp > 0 ) {
                F[ cnt ++ ] = tmp % 10 + '0' ;
                tmp /= 10 ;
            }
            while( cnt > 0 ) putchar( F[ -- cnt ] ) ;
        }
        #undef I_int
    
    }
    using namespace io ;
    
    using namespace std ;
    
    #define N 310
    
    int n, m, f[N];
    int cnt, head[N], siz[N], fa[N];
    struct edge {
    	int to, nxt;
    }e[N<<1];
    
    void ins(int u, int v) {
    	e[++cnt] = (edge) {v, head[u]};
    	head[u] = cnt;
    }
    
    void dfs(int u) {
    	siz[u] = 1;
    	for(int i = head[u]; i; i = e[i].nxt) {
    		if(e[i].to == fa[u]) continue;
    		fa[e[i].to] = u;
    		dfs(e[i].to);
    		siz[u] += siz[e[i].to];
    	}
    }
    
    struct Node {
        int val;
    };
    priority_queue<Node> q, t;
    
    bool operator < (Node a, Node b) {
        return siz[a.val] < siz[b.val];
    }
    
    int solve() {
        while(!q.empty()) q.pop();
        int ans = 0;
        q.push((Node){1});
        while(!q.empty()) {
            int cur = 0;
            while(!t.empty()) t.pop();
            while(!q.empty()) {
                int u = q.top().val; ++ans;
                for(int i = head[u]; i; i = e[i].nxt) {
                    if(e[i].to == fa[u]) continue;
                    t.push((Node){e[i].to});
                    f[++cur] = e[i].to;
                }
                q.pop();
            }
            int num;
            if(!t.empty()) {
                int u = t.top().val; t.pop();
                if(!t.empty() && rand() % 233 == 0) {
                    num = t.top().val; t.pop();
                } else num = u;
            }
            for(int i = 1; i <= cur; ++i) {
                if(f[i] == num) continue;
                q.push((Node){f[i]});
            }
        }
        return ans;
    }
    
    int main() {
    #ifndef ONLINE_JUDGE
        freopen("1.in", "r", stdin);
    #endif
        srand((unsigned)time(0));
    	n = read(), m = read();
    	for(int i = 1; i <= m; ++i) {
    		int u = read(), v = read();
    		ins(u, v); ins(v, u);
    	}
    	dfs(1);
        int ans = 1000000;
    	for(int i = 1; i <= 200; ++i) {
            ans = min(ans, solve());
        }
        printf("%d
    ", ans);
    }
    

    过段时间补个搜索做法

  • 相关阅读:
    Power of Cryptography
    Radar Installation
    Emag eht htiw Em Pleh
    Help Me with the Game
    89. Gray Code
    87. Scramble String
    86. Partition List
    85. Maximal Rectangle
    84. Largest Rectangle in Histogram
    82. Remove Duplicates from Sorted List II
  • 原文地址:https://www.cnblogs.com/henry-1202/p/10371500.html
Copyright © 2011-2022 走看看