POJ 3659 Cell Phone Network(贪心)

来源:互联网 发布:天正钢结构软件下载 编辑:程序博客网 时间:2024/05/07 01:15

基本概念:

树的支配集:对于图G = (V, E),  若点集V‘是图的一个支配集,则对于图中任意一个顶点u , 要么u属于V’,要么与V‘中顶点相邻。

而读懂题意后,这个题就是一个裸的树的最小支配集了,很多人都是用的树形dp,弱菜表示不会。。。于是。。。只好写个贪心的代码A了。。。

求树的最小支配集的贪心解法是: 选择一个点,求出dfs序列,按照得到的序列的反向序列进行贪心,对于一个既不属于支配集也不与支配集中点相连的点来说,如果他的父节点不属于支配集,将其父节点加入支配集。

同样对于树的最小点覆盖和最大独立集都能用贪心做,程序上也只需将greedy()函数修改一下。

#include<iostream>#include<algorithm>#include<vector>#include<cstdio>#include<cstring>using namespace std;const int maxn = 11111;int n, u, v, dfs_clock;int pos[maxn], p[maxn];bool vis[maxn];vector<int> G[maxn];void dfs(int u, int fa) //求树的dfs序列 保存在pos数组中{    pos[dfs_clock++] = u;    for(int i=0; i<G[u].size(); i++)    {        int v = G[u][i];        if(!vis[v] && v != fa)        {            vis[v] = 1;            p[v] = u;            dfs(v, u);        }    }}int greedy()    //贪心求树的最小支配集{    int ret = 0;    bool s[maxn] = {0};    bool set[maxn] = {0};    for(int i=n-1; i>=0; i--)    {        int t = pos[i];        if(!s[t])        {            if(!set[p[t]])            {                set[p[t]] = 1;                ret++;            }            s[t] = 1;            s[p[t]] = 1;            s[p[p[t]]] = 1;        }    }    return ret;}int main(){    while(~scanf("%d", &n))    {        for(int i=0; i<=n; i++)     G[i].clear();        for(int i=1; i<n; i++)        {            scanf("%d%d", &u, &v);            G[u].push_back(v);            G[v].push_back(u);        }        dfs_clock = 0;        memset(vis, 0, sizeof(vis));        dfs(1, -1);        printf("%d\n", greedy());    }}/* 附:int greedy() //贪心求树的最小覆盖集{    bool s[maxn] = {0};    bool set[maxn] = {0};    int ret = 0;    for(int i=n-1; i>=0; i--)    {        int t = pos[i];        if(!s[t] && !s[p[t]])        {            set[p[t]] = 1;            ret++;            s[t] = 1;            s[p[t]] = 1;        }    }    return ret;}int greedy()    //贪心求树的最大独立集{    bool s[maxn] = {0};    bool set[maxn] = {0};    int ret = 0;    for(int i=n-1; i>=0; i--)    {        int t = pos[i];        if(!s[t])        {            set[t] = 1;            ret++;            s[t] = 1;            s[p[t]] = 1;        }    }    return ret;}*/


原创粉丝点击