#NOIP模拟赛#TSP(树型DP)

27 篇文章 0 订阅
13 篇文章 0 订阅






这一题,枚举根节点。

先贴上两个性质:


定义Dp[u]表示以u为根结点,保证u的子树中所有节点都能被区分的最少信号塔数量。

因为son已经保证了其子树能被区分,所以只考虑u的直系子节点能否被区分。

如果有两个及以上的子节点,那么它们是不能被区分的,所以需要在u处放一个信号塔,从结论一得。

Code:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
using namespace std;

const int Maxn = 5000;
const int Maxm = 5000;

struct node{
    int v, nxt;
}edge[(Maxm << 1) + 5];

int N, cnt;
int Dp[Maxn + 5], fir[Maxn + 5];
char S[Maxn + 5];

bool getint(int & num){
    char c; int flg = 1;    num = 0;
    while((c = getchar()) < '0' || c > '9'){
        if(c == '-')    flg = -1;
        if(c == -1) return 0;
    }
    while(c >= '0' && c <= '9'){
        num = num * 10 + c - 48;
        if((c = getchar()) == -1)   return 0;
    }
    num *= flg;
    return 1;
}

void addedge(int a, int b){
    edge[++ cnt].v = b, edge[cnt].nxt = fir[a], fir[a] = cnt;
}

void Get_Dp(int u, int fa){
    Dp[u] = 0;
    int tot = 0;
    for(int i = fir[u]; i; i = edge[i].nxt) if(edge[i].v != fa){
        int v = edge[i].v;
        Get_Dp(v, u);
        if(! Dp[v]) ++ tot;
        else Dp[u] += Dp[v];
    }
    if(tot) Dp[u] += tot - 1;
}

int main(){
    //freopen("tps.in", "r", stdin);
    //freopen("tps.out", "w", stdout);
    getint(N);
    for(int i = 1; i <= N; ++ i){
        scanf("%s", S + 1);
        for(int j = 1; j <= N; ++ j)    if(S[j] == 'Y')
            addedge(i, j);
    }
    int Ans = N;
    for(int Root = 1; Root <= N; ++ Root){
        Get_Dp(Root, 0);
        Ans = min(Dp[Root] + 1, Ans);
    }
    printf("%d\n", Ans);
    return 0;
}




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值