• NOIP2018 保卫王国(动态DP)


    题意

    求最小权值点覆盖。

    mm次询问,每次给出两个点,分别要求每个点必须选或必须不选,输出每次的最小权值覆盖或者无解输出1-1

    题解

    强制选或者不选可以看做修改权值为±pminfin

    那么就是这道板题了。

    CODE

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    template<class T>inline void read(T &x) {
    	char ch; int flg=1; while(!isdigit(ch=getchar()))if(ch=='-')flg=-flg;
    	for(x=ch-'0';isdigit(ch=getchar());x=x*10+ch-'0'); x*=flg;
    }
    const int MAXN = 100005;
    const LL INF = 1e10;
    int n, m, fir[MAXN], nxt[MAXN<<1], to[MAXN<<1], cnt; LL V[MAXN];
    inline void link(int u, int v) {
    	to[++cnt] = v; nxt[cnt] = fir[u]; fir[u] = cnt;
    	to[++cnt] = u; nxt[cnt] = fir[v]; fir[v] = cnt;
    }
    int tmr, fa[MAXN], dfn[MAXN], tp[MAXN], bt[MAXN], son[MAXN], sz[MAXN], seq[MAXN];
    struct mat {
    	LL a[2][2];
    	LL* operator[](int x) { return a[x]; }
    	mat operator*(const mat &o)const {
    		mat re;
    		for(int i = 0; i < 2; ++i)
    			for(int j = 0; j < 2; ++j)
    				re.a[i][j] = min(a[i][0]+o.a[0][j], a[i][1]+o.a[1][j]);
    		return re;
    	}
    }t[MAXN<<2], val[MAXN];
    void dfs1(int u, int ff) {
    	fa[u] = ff; sz[u] = 1;
    	for(int i = fir[u], v; i; i = nxt[i])
    		if((v=to[i]) != ff) {
    			dfs1(v, u), sz[u] += sz[v];
    			(sz[v] > sz[son[u]]) && (son[u] = v);
    		}
    }
    LL f[MAXN][2];
    void dfs2(int u, int top) {
    	tp[u] = top; bt[top] = u;
    	seq[dfn[u]=++tmr] = u;
    	if(son[u]) dfs2(son[u], top);
    	for(int i = fir[u], v; i; i = nxt[i])
    		if((v=to[i]) != fa[u] && v != son[u])
    			dfs2(v, v);
    }
    void dp(int u) {
    	f[u][0] = V[u]; f[u][1] = 0;
    	for(int i = fir[u], v; i; i = nxt[i])
    		if((v=to[i]) != fa[u])
    			dp(v),
    			f[u][0] += min(f[v][0], f[v][1]),
    			f[u][1] += f[v][0];
    }
    void build(int i, int l, int r) {
    	if(l == r) {
    		LL f0 = V[seq[l]], f1 = 0;
    		for(int j = fir[seq[l]], v; j; j = nxt[j])
    			if((v=to[j]) != fa[seq[l]] && v != son[seq[l]])
    				f0 += min(f[v][0], f[v][1]),
    				f1 += f[v][0];
    		val[l] = t[i] = (mat){ {{f0, f0} , {f1, INF}} };
    		return;
    	}
    	int mid = (l + r) >> 1;
    	build(i<<1, l, mid);
    	build(i<<1|1, mid+1, r);
    	t[i] = t[i<<1] * t[i<<1|1];
    }
    void update(int i, int l, int r, int x) {
    	if(l == r) { t[i] = val[l]; return; }
    	int mid = (l + r) >> 1;
    	if(x <= mid) update(i<<1, l, mid, x);
    	else update(i<<1|1, mid+1, r, x);
    	t[i] = t[i<<1] * t[i<<1|1];
    }
    mat query(int i, int l, int r, int x, int y) {
    	if(x == l && r == y) return t[i];
    	int mid = (l + r) >> 1;
    	if(y <= mid) return query(i<<1, l, mid, x, y);
    	if(x > mid) return query(i<<1|1, mid+1, r, x, y);
    	return query(i<<1, l, mid, x, mid) * query(i<<1|1, mid+1, r, mid+1, y);
    }
    void modify(int u, LL W) {
    	val[dfn[u]][0][0] += W-V[u];
    	val[dfn[u]][0][1] += W-V[u];
    	V[u]=W;
    	while(u) {
    		mat pre = query(1, 1, n, dfn[tp[u]], dfn[bt[tp[u]]]);
    		update(1, 1, n, dfn[u]);
    		mat now = query(1, 1, n, dfn[tp[u]], dfn[bt[tp[u]]]);
    		u = fa[tp[u]]; if(!u) return; int x = dfn[u];
    		LL p0 = pre[0][0], p1 = pre[1][0];
    		LL n0 = now[0][0], n1 = now[1][0];
    		val[x][0][0] = val[x][0][1] = val[x][0][0] + min(n0, n1) - min(p0, p1);
    		val[x][1][0] = val[x][1][0] + n0 - p0;
    	}
    }
    map<pair<int,int>, bool>E;
    char s[10];
    int main () {
    	read(n), read(m); scanf("%s", s);
    	for(int i = 1; i <= n; ++i) read(V[i]);
    	for(int i = 1, u, v; i < n; ++i) read(u), read(v), link(u, v), E[pair<int,int>(min(u,v), max(u,v))] = 1;
    	dfs1(1, 0), dfs2(1, 1), dp(1);
    	build(1, 1, n);
    	int a, x, b, y;
    	while(m--) {
    		read(a), read(x), read(b), read(y);
    		if(!x && !y && E.count(pair<int,int>(min(a,b), max(a,b)))) {
    			puts("-1"); continue;
    		}
    		LL sum = 0;
    		LL tmpa = V[a]; modify(a, V[a] + (x ? -INF : INF)); sum += (x ? -INF : 0);
    		LL tmpb = V[b]; modify(b, V[b] + (y ? -INF : INF)); sum += (y ? -INF : 0);
    		mat ans = query(1, 1, n, 1, dfn[bt[1]]);
    		printf("%lld
    ", min(ans[0][0], ans[1][0])-sum);
    		modify(a, tmpa), modify(b, tmpb);
    	}
    }
    
  • 相关阅读:
    webpack基础理解以及使用搭建
    前端优化系列之一:dns预获取 dns-prefetch 提升页面载入速度
    react 什么是虚拟DOM?深入了解虚拟DOM
    react PropTypes 与 DefaultProps
    react todolist代码优化
    react 拆分组件于组件
    react 部分语法补充
    react 的安装和案列Todolist
    浏览器的标准模式和怪异模式
    软件测试基础——慕课网
  • 原文地址:https://www.cnblogs.com/Orz-IE/p/12039182.html
Copyright © 2020-2023  润新知