题目链接:http://poj.org/problem?id=3398

这题可以用两种上述讲的两种算法解:http://www.cnblogs.com/whatbeg/p/3776612.html

第一种,贪心算法:

贪心算法直接套一个最小支配集模板就可以了,我不能证明这样是正确的,但是能AC

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#define Mod 1000000007
using namespace std;
#define N 10007 struct Edge
{
int v,next;
}G[*N]; int fa[N];
int vis[N];
int pos[N],head[N];
int now,tot;
int n,m; void addedge(int u,int v)
{
G[tot].v = v;
G[tot].next = head[u];
head[u] = tot++;
} void DFS(int u)
{
pos[now++] = u;
for(int i=head[u];i!=-;i=G[i].next)
{
int v = G[i].v;
if(!vis[v])
{
vis[v] = ;
fa[v] = u;
DFS(v);
}
}
} int MDS()
{
int s[N] = {};
int set[N] = {};
int ans = ;
for(int i=now-;i>=;i--)
{
int t = pos[i];
if(!s[t])
{
if(!set[fa[t]])
{
set[fa[t]] = ;
ans++;
}
s[t] = ;
s[fa[t]] = ;
s[fa[fa[t]]] = ;
}
}
return ans;
} int main()
{
int n,u,v,i,j;
int op;
while(scanf("%d",&n)!=EOF)
{
tot = ;
now = ;
memset(head,-,sizeof(head));
for(i=;i<n-;i++)
{
scanf("%d%d",&u,&v);
addedge(u,v);
addedge(v,u);
}
memset(vis,,sizeof(vis));
memset(fa,-,sizeof(fa));
fa[] = ;
DFS();
int res = MDS();
printf("%d\n",res);
scanf("%d",&op);
if(op == -)
break;
}
return ;
}

第二种,树形DP。因为此时由于一台电脑不能与多台服务器连接,所以直接DP转移求最小支配集有可能不是正确解。

状态设计与上篇的相同,但是注意dp[i][0]的转移方程中,不能有dp[i][1],因为此时该子节点有一个子节点被选入最小支配集,而当前节点也被选入最小支配集,此时该子节点与两个支配集中的点相连,不符合题意。其他转移方式不变。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#define Mod 1000000007
using namespace std;
#define N 10007 struct Edge
{
int v,next;
}G[N]; int head[N],tot;
int dp[N][]; void addedge(int u,int v)
{
G[tot].v = v;
G[tot].next = head[u];
head[u] = tot++;
} void MDS_DP(int u,int fa)
{
dp[u][] = ;
dp[u][] = ;
int s = ;
int sum = ;
int inc = Mod;
for(int i=head[u];i!=-;i=G[i].next)
{
int v = G[i].v;
if(v == fa)
continue;
MDS_DP(v,u);
dp[u][] += min(dp[v][],dp[v][]);
if(dp[v][] <= dp[v][])
{
sum += dp[v][];
s = ;
}
else
{
sum += dp[v][];
inc = min(inc,dp[v][]-dp[v][]);
}
if(dp[v][] != Mod && dp[u][] != Mod)
dp[u][] += dp[v][];
else
dp[u][] = Mod;
if(inc == Mod && !s) //i没有子节点
dp[u][] = Mod;
else
{
dp[u][] = sum;
if(!s)
dp[u][] += inc;
}
}
} int main()
{
int n,u,v,i,j;
int op;
while(scanf("%d",&n)!=EOF)
{
tot = ;
memset(head,-,sizeof(head));
for(i=;i<n-;i++)
{
scanf("%d%d",&u,&v);
addedge(u,v);
addedge(v,u);
}
for(i=;i<=n;i++)
for(j=;j<=;j++)
dp[i][j] = Mod;
MDS_DP(,-);
int res = min(dp[][],dp[][]);
printf("%d\n",res);
scanf("%d",&op);
if(op == -)
break;
}
return ;
}

POJ 3398 Perfect Service --最小支配集的更多相关文章

  1. POJ 3398 Perfect Service(树型动态规划,最小支配集)

    POJ 3398 Perfect Service(树型动态规划,最小支配集) Description A network is composed of N computers connected by ...

  2. POJ 3659 Cell Phone Network / HUST 1036 Cell Phone Network(最小支配集,树型动态规划,贪心)-动态规划做法

    POJ 3659 Cell Phone Network / HUST 1036 Cell Phone Network(最小支配集,树型动态规划,贪心) Description Farmer John ...

  3. POJ 3659 Cell Phone Network(树的最小支配集)(贪心)

    Cell Phone Network Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6781   Accepted: 242 ...

  4. poj-3659 Cell Phone Network(最小支配集+贪心)

    http://poj.org/problem?id=3659 Description Farmer John has decided to give each of his cows a cell p ...

  5. 树形dp(最小支配集)

    http://poj.org/problem?id=3659 #include<iostream> #include<cstring> #include<algorith ...

  6. POJ3659 Cell Phone Network(树上最小支配集:树型DP)

    题目求一棵树的最小支配数. 支配集,即把图的点分成两个集合,所有非支配集内的点都和支配集内的某一点相邻. 听说即使是二分图,最小支配集的求解也是还没多项式算法的.而树上求最小支配集树型DP就OK了. ...

  7. 求解任意图的最小支配集(Minimun Dominating Set)

    给定一个无向图G =(V,E),其中V表示图中顶点集合,E表示边的集合.G的最小控制顶点集合为V的一个子集S∈V:假设集合R表示V排除集合S后剩余顶点集合,即R∩S=∅,R∪S=V:则最小控制顶点集合 ...

  8. 树形DP求树的最小支配集,最小点覆盖,最大独立集

    一:最小支配集 考虑最小支配集,每个点有两种状态,即属于支配集合或者不属于支配集合,其中不属于支配集合时此点还需要被覆盖,被覆盖也有两种状态,即被子节点覆盖或者被父节点覆盖.总结起来就是三种状态,现对 ...

  9. 树形DP 树的最小支配集,最小点覆盖与最大独立集

    最小支配集: 从V中选取尽量少的点组成一个集合,让V中剩余的点都与取出来的点有边相连. (点) 最小点覆盖: 从V中选取尽量少的点组成一个集合V1,让所有边(u,v)中要么u属于V1,要么v属于V1 ...

随机推荐

  1. SQL SERVER获取数据库文件信息

        MS SQL SERVER 获取当前数据库文件等信息,适用于多个版本: SELECT dbf.file_id AS FileID , dbf.name AS [FileName] , s.fi ...

  2. .Net开源项目之开源论坛

    .Net开源项目非常多,但是开源并且直接就能用的BBS项目就很少了,至少最近我在这上面没有找到一个合适的开源论坛.可能是因为我要求比较特殊,不但要开箱即用,还要用MVC+MySql开发. Discuz ...

  3. 常用Keytool 命令

    常用Keytool 命令Keytool 是一个JAVA环境下的安全钥匙与证书的管理工具.它管理一个存储了私有钥匙和验证相应公共钥匙的与它们相关联的X.509 证书链的keystore(相当一个数据库, ...

  4. Linux编辑器vim键盘详解

    下面的这张图,一看就明白了,从此,学习变的不再艰难! 补注:图中没有关于查找和替换的,应该用下面的.自上而下的查找操作                  /word小写的n和N自下而上的查找操作    ...

  5. [C/C++] VS 2015 C++ 插件

    Visual Studio2015 Community一些必备插件 ReSharper C++ 各种语言版本的代码重构,代码风格,代码修正功能,非常强大,可惜不是免费的,不过好在可以破解呢. Vias ...

  6. [android] 手机卫士设置向导页面

    设置向导页面,通过SharedPreferences来判断是否已经设置过了,跳转到不同的页面 自定义样式 在res/values/styles.xml中 添加节点<style name=””&g ...

  7. iOS-代理反向传值<转>

    在上篇博客 iOS代理协议 中,侧重解析了委托代理协议的概念等,本文将侧重于它们在开发中的应用. 假如我们有一个需求如下:界面A上面有一个button.一个label.从界面A跳转到界面B,在界面B的 ...

  8. CoreAnimation-06-CAKeyframeAnimation

    概述 简介 CAKeyframeAnimation又称关键帧动画 CAKeyframeAnimation是抽象类CAPropertyAnimation的子类,可以直接使用 通过values与path两 ...

  9. java网络---基本web概念

    首先需要搞清楚web中的3个关键概念. 一.HTTP,HTML,URL. HTML 全称是Hypertext Markup Language,是用来描述一个网页的语言.或者说,该语言是用来描述网页的“ ...

  10. 静态代码检查工具-PMD初学者入门篇

    前言: PMD是一款静态代码分析工具,它能够自动检测各种潜在缺陷以及不安全或未优化的代码. PMD更多地是集中在预先检测缺陷上,它提供了高度可配置的丰富规则集,用户可以方便配置对待特定项目使用那些规则 ...