zoukankan      html  css  js  c++  java
  • [51nod1314] 定位系统

    题意:给你一棵树,要求你选择一些点建立信号站,使得每一个点到这些信号站的距离数组dis都不一样(注意是数组不一样)

    题解:

    树形dp

    1、若在两点x,y建立信号站,那么x->y路径上的所有点的dis数组都不一样

    2、考虑选择一个点为根并标记,那么尽量选择叶子标记,这样链越长,贡献越大

    3、若某个结点的子树为多叉树,那么至多可以有一条链形子树的叶子不需要标记,因为这条链上的结点可以被其他子树标记的点影响

    4、特判:n=1时,答案为0。当树退化成链时,当前的根节点不需要标价

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define ll long long
    #define N 55
    using namespace std;
    
    int e_num,dp[N],t[N],nxt[N*2],to[N*2],h[N];
    char s[55];
    
    int gi() {
      int x=0,o=1; char ch=getchar();
      while(ch!='-' && (ch<'0' || ch>'9')) ch=getchar();
      if(ch=='-') o=-1,ch=getchar();
      while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
      return o*x;
    }
    
    void add(int x, int y) {
      nxt[++e_num]=h[x],to[e_num]=y,h[x]=e_num;
    }
    
    void dfs(int u, int fa) {
      dp[u]=0,t[u]=0;
      int flg=0;
      for(int i=h[u]; i; i=nxt[i]) {
        int v=to[i];
        if(v==fa) continue;
        if(!t[u]) t[u]=1;
        else t[u]=2;
        dfs(v,u);
        dp[u]+=dp[v];
        if(t[v]<=1) flg=1;//有一个子树为链
        else if(t[v]) t[u]=2;//表示它并非一条链的形式
      }
      if(t[u]==2) dp[u]-=flg;
      if(!t[u]) dp[u]=1;
    }
    
    int main() {
      int n=gi(),ans=1<<30; 
      if(n==1) {puts("0");return 0;}
      for(int i=1; i<=n; i++) {
        scanf("%s", s+1);
        for(int j=1; j<=n; j++) {
          if(s[j]=='Y') add(i,j);
        }
      }
      for(int i=1; i<=n; i++) {
        dfs(i,0);
        dp[i]+=(t[i]==2);
        ans=min(ans,dp[i]);
      }
      printf("%d", ans);
      return 0;
    }
  • 相关阅读:
    sql 事务
    GridView数据导入Excel
    图片对比度亮度调节函数
    在.NET(C#)中获取电脑名IP地址及当前用户名
    一个简单的存储过程
    通用海量数据库翻页
    Graphics
    sql 触发器
    DataTable中的数据导出Excel文件
    窗口渐变
  • 原文地址:https://www.cnblogs.com/HLXZZ/p/7597595.html
Copyright © 2011-2022 走看看