Poj1463 及 Poj3659 树形贪心建立解

来源:互联网 发布:软件测试教程 网盘 编辑:程序博客网 时间:2024/06/03 16:17

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;}/*91 22 33 44 55 65 74 88 981 22 33 43 52 66 76 8*/


 

 

原创粉丝点击