【POJ3659】【USACO 2008 Jan Gold】 3.Cell Phone Network 树上最小支配集/贪心 两种做法

题意:求树上最小支配集

最小支配集:点集,即每个点可以“支配”到相邻点,求最少点数可以使所有点被支配。

图上的最小支配集是NP的,但是树上的可以DP做,是O(n)的。

暴力做就好了,

f[i]表示此 点被选时的子树全支配的最小代价

g[i]表示其父亲节 点被选时的子树全支配的最小代价

h[i]表示其某子节 点被选时的子树全支配的最小代价

然后暴力转移。

(v是子节点)

f[x]=∑(min(f[v],min(g[v],h[v])))+1;

g[x]=∑(min(f[v],h[v]));

h[x]: Ⅰ. 某个f[v]<=h[v]:h[x]=g[x]

Ⅱ. 取个影响最小的f[v],即此v有f[v]-h[v]最小。其它v取min(f[v],h[v])此时即h[v]

呃,这个是正规做法,先附个代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 10100
#define inf 0x3f3f3f3f
using namespace std;
struct KSD
{
	int v,next;
}e[N<<1];
int head[N],cnt;
void add(int u,int v)
{
	cnt++;
	e[cnt].v=v;
	e[cnt].next=head[u];
	head[u]=cnt;
}
int n,f[N],g[N],h[N];
// 亮、父亮、子亮
void Tree_DP(int x,int p)
{
	int i,v,temp=20000;
	f[x]=1;
	bool flag=1,flag2=0;
	for(i=head[x];i;i=e[i].next)
	{
		v=e[i].v;
		if(v==p)continue;
		Tree_DP(v,x);
		f[x]+=min(f[v],min(g[v],h[v]));
		g[x]+=min(f[v],h[v]);
		temp=min(temp,f[v]-h[v]);
		if(f[v]<=h[v])flag2=1;
		flag=0;
	}
	if(flag)h[x]=inf;
	else {
		h[x]=g[x];
		if(!flag2)h[x]+=temp;
	}
	return ;
}
int main()
{
//	freopen("test.in","r",stdin);
	int i,j,k;
	int a,b,c;
	scanf("%d",&n);
	for(i=1;i<n;i++)
	{
		scanf("%d%d",&a,&b);
		add(a,b),add(b,a);
	}
	Tree_DP(1,0);
	printf("%d\n",min(f[1],h[1]));
	return 0;
}

再附个很久以前写的贪心:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define N 10100
typedef struct KSD{int v,next;}ksd;ksd e[2*N];
int head[N],n,ans;
int attack[N],killed[N];
void add(int note,int u,int v){e[note].v=v;e[note].next=head[u];head[u]=note;}
void init()
{
	ans=0;
	memset(head,-1,sizeof(head));
	memset(attack,0,sizeof(attack));
	memset(killed,0,sizeof(killed));
}
void dfs(int x,int p)
{
	int i,j,k,t,v;
	for(t=head[x];t!=-1;t=e[t].next)
	{
		if(e[t].v!=p)
		dfs(e[t].v,x);
	}
	if(killed[x]==0)
	{
		ans++;
		attack[p]=killed[x]=killed[p]=1;
		for(t=head[p];t!=-1;t=e[t].next)
		{
			killed[e[t].v]=1;
		}
	}
}

int main()
{
//	freopen("test.in","r",stdin);
	int i,j,k;
	int a,b,c;
	while(scanf("%d",&n)!=EOF)
	{
		init();
		for(i=1;i<n;i++)
		{
			scanf("%d%d",&a,&b);
			add(i*2-1,a,b);
			add(i*2,b,a);
		}
		dfs(1,0);
		printf("%d\n",ans);
	}
	return 0;
时间: 2024-10-27 04:57:28

【POJ3659】【USACO 2008 Jan Gold】 3.Cell Phone Network 树上最小支配集/贪心 两种做法的相关文章

POJ3659 Cell Phone Network【最小支配集】【贪心】

Cell Phone Network Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 5735Accepted: 2053 Description Farmer John has decided to give each of his cows a cell phone in hopes to encourage their social interaction. This, however, requires him to

poj3659 Cell Phone Network(最小支配集-树形dp)

题目链接:点击打开链接 题目描述:给定一棵树,从中选取尽量少的点使每个点要么被选中,要么和被选中的点直接相连? 解题思路:树上的最小支配集,树形dp dp[i][0]:选中i作为支配集 dp[i][1]:不选i作为支配集,但其子节点覆盖了i dp[i][2]:不选i作为支配集,而且其子节点没有覆盖i 代码: #pragma comment(linker,"/STACK:1024000000,1024000000") #include <cstdio> #include &l

【POJ3657】【USACO 2008 Jan Gold】 1.Haybale Guessing 二分答案,并查集check

题意: 输入n.m表示数列长度为n,有m条有序的限制{l,r,x}. 限制:l~r间所有数最小值为x. 问到第几条限制开始出现矛盾,都不出现输出"0". 题解: 首先这题比较厉害,正常解有点难,不妨转化成二分答案. 我们二分"答案",也就是第ans条出现矛盾. 考虑到若一条限制S所在区间被另一个限制Seg包含,且Seg这条限制的x又比S.x大, 那么也就是意为 ① [Seg.l,Seg.r]间最小值为Seg.x ② [S  .l,S  .r]间最小值为S  .x ③

【POJ3658】【USACO 2008 Jan Gold】 2.Artificial Lake人工湖 单调栈

人工湖 Time Limit: 1 Sec  Memory Limit: 128 MB Description 夏日那让人喘不过气的酷热将奶牛们的烦躁情绪推到了最高点.最终,FJ 决定建一个人工湖供奶牛消暑之用.为了使湖看起来更加真实,FJ决定将湖的 横截面建成N(1 <= N <= 100,000)个连续的平台高低错落的组合状,所有的平台 从左到右按1..N依次编号.当然咯,在湖中注入水后,这些平台都将被淹没. 平台i在设计图上用它的宽度W_i(1 <= W_i <= 1,000

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

题目求一棵树的最小支配数. 支配集,即把图的点分成两个集合,所有非支配集内的点都和支配集内的某一点相邻. 听说即使是二分图,最小支配集的求解也是还没多项式算法的.而树上求最小支配集树型DP就OK了. 树上的每个结点作为其子树的根可以有三个状态: 不属于支配集且还没被支配 不属于支配集但被其孩子支配 属于支配集 那么就是用dp[u][1\2\3]来表示动归的状态. 123转移该怎么转移就怎么转移..最后的结果就是min(dp[root][2],dp[root][3]). 要注意的是对于有些结点前2

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

Cell Phone Network Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6781   Accepted: 2429 Description Farmer John has decided to give each of his cows a cell phone in hopes to encourage their social interaction. This, however, requires hi

bzoj2581 [USACO 2012 Jan Gold] Cow Run【And-Or Tree】

传送门1:http://www.usaco.org/index.php?page=viewproblem2&cpid=110 传送门2:http://www.lydsy.com/JudgeOnline/problem.php?id=2581 这题我一看就知道自己不会了,只想了个O(2^n * 2 ^ n)即O(2 ^ 2n)的大暴力,也懒得打了,果断看solution. 看了之后惊呆了,看到了一种从未见过,闻所未闻的树叫做And-Or Tree,百度了一下,并没有官方中文翻译,姑且叫他"

【BZOJ1229】【USACO 2008 Nov Gold】 4.Toys sadstory 三分+贪心

sad story:我们自己oj的数据貌似有点问题.标程WA了5% 题解: 复制去Google翻译翻译结果 首先引一下VFK神犇的证明来证明一下这道题是三分.. { 我来告诉你世界的真相 = = 因为这题能最小费用最大流 每次最短路长度不降 所以是单峰的 最短路长度就是差分值.. 所以一阶导不降.. 是不是简单粗暴 你要证函数是单峰的. 当然是证斜率什么的 } 三分完初始买了多少个玩具,然后就是贪心. 首先我想说这个贪心真动规.虽然它真的是贪心. 首先先说一种错误的贪心. 就是从前往后扫,优先用

USACO 2011 Jan Gold 3. Roads and Planes

题意: 给出一个n个结点m条边有向图,可能有负权边: 但是存在负权边a->b则不会有某个路径可以从b到a: 求一个源点s到所有点的最短路(无解输出"NO PATH"): n<=25000,m<=150000: 题解: 高高兴兴的写了一发spfa,O(km)嘛: 然后就TLE了,这题丧心病狂的把spfa卡掉了: 这时候理所当然的想到了dij+heap,写到一半想起来不支持负权边: 所以这个不是一个简单的单源最短路问题: 题中有一个重要条件就是负权边不会回去: 我本以为只