zoukankan      html  css  js  c++  java
  • BZOJ2466: [中山市选2009]树

    BZOJ2466: [中山市选2009]树

    https://lydsy.com/JudgeOnline/problem.php?id=2466

    分析:

    • 半年前写的高斯消元调不出来了。
    • 现在来看这道题不是沙茶树形dp?
    • (f[x][0/1][0/1])表示(x)的子树不包含(x)都亮了,(x)按没按,(x)亮不亮。
    • 然后转移即可。

    代码:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cstdlib>
    #include <vector>
    #include <iostream>
    #include <cmath>
    #include <set>
    using namespace std;
    #define N 150
    int head[N],to[N<<1],nxt[N<<1],cnt,n,f[N][2][2];
    inline void add(int u,int v) {
    	to[++cnt]=v; nxt[cnt]=head[u]; head[u]=cnt;
    }
    int vis[N][2];
    void dfs(int x,int y) {
    	int i;
    	f[x][1][0]=f[x][1][1]=1;
    	for(i=head[x];i;i=nxt[i]) if(to[i]!=y) {
    		dfs(to[i],x);
    	}
    	int mn[2],cc[2]; mn[0]=mn[1]=cc[0]=cc[1]=0;
    	for(i=head[x];i;i=nxt[i]) if(to[i]!=y) {
    		int t=to[i];
    		if(f[t][0][0]<f[t][1][0]) {
    			mn[0]+=f[t][0][0];
    			vis[t][0]=0;
    		}else {
    			mn[0]+=f[t][1][0];
    			cc[0]++;
    			vis[t][0]=1;
    		}
    		if(f[t][0][1]<f[t][1][1]) {
    			mn[1]+=f[t][0][1];
    			vis[t][1]=0;
    		}else {
    			mn[1]+=f[t][1][1];
    			cc[1]++;
    			vis[t][1]=1;
    		}
    	}
    	int d;
    	d=n+1;
    	for(i=head[x];i;i=nxt[i]) if(to[i]!=y) {
    		int t=to[i];
    		if(vis[t][1]==0) d=min(d,f[t][1][1]-f[t][0][1]);
    		else d=min(d,f[t][0][1]-f[t][1][1]);
    	}
    	if(cc[1]&1) {
    		f[x][0][1]=mn[1];
    		f[x][0][0]=mn[1]+d;
    	}else {
    		f[x][0][0]=mn[1];
    		f[x][0][1]=mn[1]+d;
    	}
    	d=n+1;
    	for(i=head[x];i;i=nxt[i]) if(to[i]!=y) {
    		int t=to[i];
    		if(vis[t][0]==0) d=min(d,f[t][1][0]-f[t][0][0]);
    		else d=min(f[t][0][0],f[t][1][0]);
    	}
    	if(cc[0]&1) {
    		f[x][1][0]+=mn[0];
    		f[x][1][1]+=mn[0]+d;
    	}else {
    		f[x][1][1]+=mn[0];
    		f[x][1][0]+=mn[0]+d;
    	}
    }
    int main() {
    	while(scanf("%d",&n)!=EOF&&n) {
    		memset(f,0,sizeof(f));
    		memset(head,0,sizeof(head)); cnt=0;
    		int i,x,y;
    		for(i=1;i<n;i++) scanf("%d%d",&x,&y),add(x,y),add(y,x);
    		dfs(1,0);
    		printf("%d
    ",min(f[1][0][1],f[1][1][1]));
    	}
    }
    
  • 相关阅读:
    记录Integer比较问题
    代码中获取git输出
    python open mode
    elasticsearch Unrecognized VM option 'UseParNewGC'
    应用商店显示无法加载页面 请稍后重试
    deep learning with python前五章笔记
    QWeb2: Template 'systray_odoo_referral.gift_icon' not found
    wifi scapy
    struct.pack, struct.unpack详解
    python f-string
  • 原文地址:https://www.cnblogs.com/suika/p/10205555.html
Copyright © 2011-2022 走看看