poj 3659 Cell Phone Network(最小支配集)
Problem 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 set up cell phone towers on his N (1 ≤ N ≤ 10,000) pastures (conveniently numbered 1..N) so they can all communicate.
Exactly N-1 pairs of pastures are adjacent, and for any two pastures A
Help him determine the minimum number of towers he must install to provide cell phone service to each pasture.
Input
<p>* Line 1: A single integer: <i>N</i><br>* Lines 2..<i>N</i>: Each line specifies a pair of adjacent pastures with two space-separated integers: <i>A</i> and <i>B</i></p>
Output
<p>* Line 1: A single integer indicating the minimum number of towers to install</p>
Sample Input
5 1 3 5 2 4 3 3 5
Sample Output
2
n個點,農場主準備給每個點的牛一個電話,如果在某點設立電線杆,那麼其相連的點和當前點都可以互相通電話,請問最少設立多少個電線杆才能使得所有點的牛都可以互相打電話。
樹的最小支配集,這裡用貪心
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=20020;
struct edge
{
int v,next;
}edge[maxn];
bool vis[maxn];
int head[maxn];
int father[maxn];
int newpos[maxn];
int n,now,cnt;
void init()
{
memset(head,-1,sizeof(head));
cnt=0;
memset(father,0,sizeof(father));
memset(newpos,0,sizeof(newpos));
memset(vis,0,sizeof(vis));
memset(edge,0,sizeof(edge));
}
void addedge(int u,int v)
{
edge[cnt].v=v;
edge[cnt].next=head[u];
head[u]=cnt++;
}
void dfs(int x)
{
newpos[now++]=x;
for(int i=head[x];i!=-1;i=edge[i].next)
{
if(!vis[edge[i].v])
{vis[edge[i].v]=1;
father[edge[i].v]=x;
dfs(edge[i].v);
}
}
}
bool s[maxn],set[maxn];
int greedy()
{
memset(s,0,sizeof(s));
memset(set,0,sizeof(set));
int ans=0;
for(int i=n;i>=1;i--)
{
int t=newpos[i];
if(!s[t])
{
if(!set[father[t]])
{set[father[t]]=1;
ans++;
}
s[t]=1;
s[father[t]]=1;
s[father[father[t]]]=1;
}
}
return ans;
}
int main()
{while(~scanf("%d",&n))
{int u,v;
init();
for(int i=1;i<=n-1;i++)
{scanf("%d%d",&u,&v);
addedge(u,v);
addedge(v,u);}
now=0;
dfs(1);
printf("%d\n",greedy());
}
return 0;
}