Poj1463
题目链接:http://poj.org/problem?id=1463
题意:给出一个树形图,在某个节点上放置一个卫兵可以管辖周围所有与该节点相连的边,问最少需要放置多少个卫兵,能管辖所有的边。
贪心思路是,叶节点不放置卫兵,则其父亲节点必放置卫兵以覆盖该边,自叶节点向上的过程中,如果某节点含有未被覆盖的通向子节点的边,则此节点放置卫兵。
Poj3659
题目链接:http://poj.org/problem?id=3659
题意:同样是一个树形图,在某个节点上放置一个信号塔,可以覆盖所有与其相邻的其它节点,问最少需要放置多少个信号塔,用以覆盖所有的节点。
乍一看与上一题一样,可是仔细分析不难发现,这一题中要求的是覆盖所有节点,即与上一题不同之处在于,如果一个节点被其子节点覆盖的话,其父节点就不需要放置信号塔
来覆盖它,这样就有边未被覆盖,但达到了此题的要求,具体做法是,对每一个节点的覆盖分三种情况考虑:
1、被子节点放置的信号塔覆盖;
2、本身放置了信号塔;
3、本身既未放置信号塔,也未被子节点覆盖。
同1463一样,实现过程中从叶节点到根进行贪心决策,叶节点置情况为3,则,如果某一节点其子节点有3 这种情况,该节点必定置2状态,否则视其是否被子节点放置情况覆
盖取1、2两种状态, 要另外说明的一点是,如果执行至根节点时,其状态为3,则是需要另外放置一个信号塔,因为没有父节点能覆盖它。
Poj1463 Code
#include<stdio.h>
#include<string.h>
int l[1508];
int s[1508];
int vis[1508];
int map[1508][16];
int n;
int Dfs(int u)
{
int place=0,i,r=0;
vis[u]=1;
for(i=0;i<l[u];i++){
if(vis[map[u][i]]) continue;
r+=Dfs(map[u][i]);
if(!s[map[u][i]])
place=1;
}
return r+(s[u]=place);
}
int main()
{
int i,j,u,v,e;
while(~scanf("%d",&n)){
memset(l,0,sizeof(l));
memset(s,0,sizeof(s));
memset(vis,0,sizeof(vis));
for(i=0;i<n;i++){
scanf("%d",&u);
scanf(":(%d)",&e);
for(j=0;j<e;j++){
scanf("%d",&v);
map[u][l[u]++]=v;
map[v][l[v]++]=u;
}
}
printf("%d\n",Dfs(0));
}
return 0;
}
Poj 3659 Code
#include<stdio.h>
#include<string.h>
struct{
int v,next;
}edg[20016];
int s[10008];
int vis[10008];
int head[10008];
int n,e;
int Dfs(int u)
{
int place=0,tmp,r=0;
vis[u]=1;
for(tmp=head[u];tmp!=-1;tmp=edg[tmp].next){
if(vis[edg[tmp].v]) continue;
r+=Dfs(edg[tmp].v);
if(place==2) continue;
if(s[edg[tmp].v]==0)place=2;
if(s[edg[tmp].v]==2)place=1;
}s[u]=place;//0表示当前节点未被子节点覆盖,1表被子节点覆盖,2表示
//需要覆盖子节点。
return r+(place>>1);//由增加的一个节点0来简化根节点的判断,即根节
//点如果不需要覆盖子节点,又没有父节点将其覆盖
//此种待殊情况。
}
int main()
{
int i,u,v;
while(~scanf("%d",&n)){
memset(s,0,sizeof(s));
memset(vis,0,sizeof(vis));
memset(head,-1,sizeof(head));
e=0;
for(i=1;i<n;i++){
scanf("%d%d",&u,&v);
edg[e].v=v;edg[e].next=head[u];head[u]=e++;
edg[e].v=u;edg[e].next=head[v];head[v]=e++;
}edg[e].v=1;edg[e].next=head[0];head[0]=e++;
printf("%d\n",Dfs(0));
scanf("%d",&u);
if(u==-1) break;
}
return 0;
}
/*
9
1 2
2 3
3 4
4 5
5 6
5 7
4 8
8 9
8
1 2
2 3
3 4
3 5
2 6
6 7
6 8
*/