zoukankan      html  css  js  c++  java
  • 紫书 例题 9-14 UVa 1218 (树形dp)

    这道题有个初始值设成1e9, 然后这个值是要加很多次的,然后就会溢出变成负数,
    然后就一直WA, 找这个bug找了一个小时……以后不能随便这样设那么大,
    要考虑会不会加很多次然后溢出。

    讲一下思路。
    首先对于当前节点u,可以分三种情况。
    一种是当前节点是服务器,一种是节点的父亲是服务器,一种是节点的儿子是服务器。
    不可能都不是服务器,因为如果这样的话u自己就没有服务器相连。
    设本身是服务器的为d(u, 0),父亲是服务器为d(u, 1),儿子是服务器是d(u, 2)
    那么我们可以写出转移方程
    d(u, 0):此时u的儿子可以是服务器也可以不是服务器,所以d[u][0] = sum{min(d(v, 0),d(v, 1)) | v是u的儿子} + 1(本身)
    d(u, 1):此时u的儿子全部都不是服务器,因为父亲已经是,只能和一个服务器相连。,所以d(u, 1) = sum{d(v, 2)| v是u的儿子}
    d(u, 2):此时u的节点中一定有且只有一个儿子有服务器,所以我们可以枚举这个儿子是哪一个,设这个儿子是q, 其他的所有儿子是p, 那么d(u, 2) = min(d(q, 0) + sum(d(p, 2)))
    但是这样非常的耗时间,我们可以利用前面的式子代换一下。
    我们观察 sum(d(p, 2)), p是除了q以外的所有儿子,所以可以用所有儿子的值减去q的值,
    也就是sum(d(p, 2)) = sum(d(v, 2)) - d(q, 2) = d(u, 1) - d(q, 2)。所以枚举q取最小的就好了。
    以0为根节点,最后输出min(d(0, 0), d(0, 2)), 根节点没有父节点,所以d(0, 1)不理他
     

    #include<cstdio>
    #include<vector>
    #include<algorithm>
    #define REP(i, a, b) for(int i = (a); i < (b); i++)
    using namespace std;
    
    const int MAXN = 11234;
    int d[MAXN][3], n;
    vector<int> g[MAXN];
    
    void dfs(int u, int fa)
    {
    	d[u][1] = 0; d[u][0] = 1;
    	if(g[u].size() == 1 && fa != -1) return;
    	
    	REP(i, 0, g[u].size())
    	{
    		int v = g[u][i];
    		if(v == fa) continue;
    		dfs(v, u);
    		d[u][1] += d[v][2];
    		d[u][0] += min(d[v][1], d[v][0]);
    	}
    	
    	REP(i, 0, g[u].size())
    	{
    		int v = g[u][i];
    		if(v == fa) continue;
    		d[u][2] = min(d[u][2], d[u][1] - d[v][2] + d[v][0]);
    	}
    }
    
    int main()
    {
    	while(~scanf("%d", &n))
    	{
    		REP(i, 0, n) g[i].clear(), d[i][2] = MAXN + 1;
    		REP(i, 0, n - 1)
    		{
    			int a, b;
    			scanf("%d%d", &a, &b);
    			a--; b--;
    			g[a].push_back(b);
    			g[b].push_back(a);
    		}
    		
    		dfs(0, -1);
    		printf("%d
    ", min(d[0][0], d[0][2]));
    		scanf("%d", &n);
    	}
    	return 0;
    }
  • 相关阅读:
    InfoPath 发布表单到SharePoint库报错
    在log4net中控制nhibernate输出
    微信扫一扫(wx.scanQRCode)功能新手可能遇到的问题
    3.Zookeeper的安装和配置(集群模式)
    1.配置HDFS HA (高可用)
    2.Zookeeper工作原理(详细)
    1.Zookeeper 定义与工作原理
    js 获取元素的几种方法
    弹出层居中
    XUACompatible
  • 原文地址:https://www.cnblogs.com/sugewud/p/9819447.html
Copyright © 2011-2022 走看看