UVA - 1267(贪心)

来源:互联网 发布:c语言基础入门 编辑:程序博客网 时间:2024/04/24 11:14

先根据根服务器位置,将五根树转换为有根树,

然后,每次深度最大的未被覆盖到的节点,选其k级祖先做服务器、证明,就是假设法。

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <vector>#include <cmath>#include <map>#include <set>#include <cctype>using namespace std;typedef long long LL;#define rep(i,n) for(int (i)=0;(i)<(n);(i)++)#define rep1(i,n) for(int (i)=1;(i)<=(n);(i)++)const int maxn = 1110;vector<int> G[maxn];int sx,k,n;struct node{  int id,dep;  bool operator <(const node& a)const{    return dep<a.dep;  }}a[maxn];int fat[maxn];vector<node> ans;void dfs(int u,int fa,int depth){  a[u].id = u; a[u].dep = depth;  fat[u] = fa;  if(G[u].size()==1&&G[u][0]==fa){      if(depth > k) ans.push_back(a[u]);      return ;  }  for(int i=0;i<G[u].size();i++){      int v = G[u][i];      if(v==fa) continue;      dfs(v,u,depth+1);  }}int vis[maxn];void kuo(int u,int fa,int tk){   vis[u] = 1;   for(int i=0;i<G[u].size();i++){      int v = G[u][i];      if(v == fa) continue;      if(tk<k) kuo(v,u,tk+1);   }}int find_fa(int x,int d){  return (d == k ? x:find_fa(fat[x],d+1));}int main(){    int T;    scanf("%d",&T);    while(T--){      scanf("%d %d %d",&n,&sx,&k);      rep1(i,n) G[i].clear();      rep(i,n-1){        int x,y;        scanf("%d %d",&x,&y);        G[x].push_back(y);        G[y].push_back(x);      }      ans.clear();      dfs(sx,-1,0);      memset(vis,0,sizeof(vis));      if(ans.size()>0){        sort(ans.begin(),ans.end());      }      int res = 0;      kuo(sx,-1,0);      if(ans.size()>0)      for(int i=ans.size()-1;i>=0;i--){         int v = ans[i].id;         if(!vis[v]){            kuo(find_fa(v,0),-1,0);            res++;         }      }      printf("%d\n",res);    }    return 0;}



0 0
原创粉丝点击