题目链接: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[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 n,u,v,i,j; int op; while(scanf("%d",&n)!=EOF) { tot = 1; now = 0; memset(head,-1,sizeof(head)); for(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; }