zoukankan      html  css  js  c++  java
  • UVA1218 完美的服务 Perfect Service TJ

    题目链接

    补充

    样例输入

    6
    1 3
    2 3
    3 4
    4 5
    4 6
    0
    2
    1 2
    -1

    样例输出

    2
    1

    思路

    题目描述了一个树形结构,我们考虑使用树形 (DP) ,由于多了一个限制条件:一个客户端只有一个服务器。
    那么我们设置三种状态:
    (dp[u][0]) 表示当前节点 (u) 为服务器,孩子是否为服务器均可,
    (dp[u][1]) 表示当前节点 (u) 为客户端, (u) 的父亲为服务器, (u) 的儿子均为客户端,
    (dp[u][2]) 表示当前节点 (u) 为客户端, (u) 的父亲为客户端, (u) 的其中一个儿子为服务器。

    第一个比较容易得到 (dp[u][0] = sum dp[v][1] + 1.)
    第二个比较容易得到 (dp[u][1] = sum dp[v][2].)

    下面我们分析第三个,容易得到 (dp[u][2] = min (dp[u][2] ,dp[V][0] + sum dp[v][2]).(V != v))
    但是时间复杂度过于太高,那么我们考虑进行优化:
    可以发现,(sum dp[v][2] = dp[u][1].) ,那么 (sum dp[v][2] + dp[V][0] = dp[u][1] - dp[V][2] + dp[V][0].)
    可得状态转移方程: (dp[u][2] = min (dp[u][2] ,dp[u][1] - dp[V][2] + dp[V][0]).)

    易错:初始化。

    代码

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cstdlib>
    using namespace std;
    const int MAXN = 1e4 + 10;
    struct node {
    	int next ,to;
    }edge[MAXN << 1];
    int head[MAXN] ,cnt = 0;
    void add (int from ,int to) {
    	edge[++ cnt].next = head[from];
    	head[from] = cnt;
    	edge[cnt].to = to;
    	return ;
    }
    int n ,dp[MAXN][3] ,rt;
    void dfs (int u ,int fa) {
    	dp[u][0] = 1 ,dp[u][1] = 0;
    	dp[u][2] = 10010;
    	for (int q = head[u];~ q;q = edge[q].next) {
    		int v = edge[q].to;
    		if (v == fa) continue;
    		dfs (v ,u);
    		dp[u][0] += min (dp[v][0] ,dp[v][1]);
    		dp[u][1] += dp[v][2];
    	}
    	for (int q = head[u];~ q;q = edge[q].next) {
    		int v = edge[q].to;
    		if (v == fa) continue;
    		dp[u][2] = min (dp[u][2] ,dp[u][1] - dp[v][2] + dp[v][0]);
    	}
    	return ;
    }
    void solve () {
    	rt = 1;
    	dfs (rt ,0);
    	printf ("%d
    ",min (dp[rt][2] ,dp[rt][0]));
    	return ;
    }
    int main () {
    	int cmp ,from ,to;
    	while (scanf ("%d",&n)) {
    		memset (head ,-1 ,sizeof (head));
    		cnt = 0;
    		for (int q = 1;q < n;++ q) {
    			scanf ("%d%d",&from ,&to);
    			add (from ,to) ,add (to ,from);
    		}
    		solve ();
    		scanf ("%d",&cmp);
    		if (cmp == -1) break;
    	}
    	return 0;
    }
    
    
    cb
  • 相关阅读:
    Java中synchronized的使用实例
    Javaweb异常提示信息统一处理
    Java异常封装
    Java经典设计模式之十一种行为型模式
    Java经典设计模式之七大结构型模式
    java多线程快速入门(十二)
    java多线程快速入门(十一)
    java多线程快速入门(十)
    java多线程快速入门(九)
    java多线程快速入门(八)
  • 原文地址:https://www.cnblogs.com/tuscjaf/p/13894231.html
Copyright © 2011-2022 走看看