第一种,贪心算法:
贪心算法直接套一个最小支配集模板就可以了,但却不能证明这样是堆的,但是能AC
//最小支配集贪心模板
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=10007;
struct edge{
int v,next;
};
edge G[2*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!=-1;i=G[i].next){
int v=G[i].v;
if(!vis[v]){
vis[v]=1;
fa[v]=u;
dfs(v);
}
}
}
int mds()
{
int s[N]={0};
int set[N]={0};
int ans=0;
for(int i=now-1;i>=0;i--){
int t=pos[i];
if(!s[t]){
if(!set[fa[t]]){
set[fa[t]]=1;
ans++;
}
s[t]=1;
s[fa[t]]=1;
s[fa[fa[t]]]=1;
}
}
return ans;
}
int main()
{
int op;
while(scanf("%d",&n)!=EOF){
tot=1;
now=0;
int u,v;
memset(head,-1,sizeof(head));
for(int i=0;i<n-1;i++){
scanf("%d%d",&u,&v);
addedge(u,v);
addedge(v,u);
}
memset(vis,0,sizeof(vis));
memset(fa,-1,sizeof(fa));
fa[1]=1;
dfs(1);
int res=mds();
printf("%d\n",res);
scanf("%d",&op);
if(op==-1){
break;
}
}
return 0;
}
第二种:树形动态规划
以后更新