[NOIP模拟赛]TPS

来源:互联网 发布:阿里云终端管理工具 编辑:程序博客网 时间:2024/06/05 03:32

题目描述
Treelandn个城市,标号从1...n(1≤n≤5000)。有n-1条双向道路连接了n个城市构成一颗树。
Treeland的居民想要建造一套 TPS系统(Treeland Positioning System)TPS是一个能帮助人定位他在哪个城市的系统。系统由k个信号塔构成,每个信号塔被安放在一个城市。当一个人打开他的TPS接收器的时候他能得到他与每一个信号塔的距离(这里距离指树上两点之间经过的边的数量) 
显然只有当在不同的城市打开TPS接收器接受到的信息不一样的时候TPS系统才能正常工作。(也就不存在两个不同的城市使得在他们那里接收到的信号相同)注意不同的信号塔之间是可以区分的

求最少安放多少信号塔才能使TPS系统正常工作。


输入格式
1行:1个整数n,表示结点数
接下来n行,第i1个字符串,第j个字符为'Y',表示城市ij之间有一条道路。该字符为'N',则表示两个城市之间没有道路
 
输入样例
4
NYYY
YNNN
YNNN
YNNN
 
输出样例
2
 
样例说明
4个城市,道路图如下所示:
2 - 1 - 3
    |

    4

1个信号塔是不够的,因为如果它放置在城市1,那么城市234的距离都与那个信号塔有1距离,它们是无法区分的。如果它位于2号城市,那么34号城市都有2的距离,它们是无法区分的。

2个信号塔则足够了,因为如果把两个信号塔放置在城市23,那么:如果我们在城市1,接收器会显示距离1,1。如果我们在城市2,接收器将显示距离0,2。如果我们在城市3,接收器会显示距离2,0。如果我们在城市4,接收器会显示距离2,2

在每个城市里,接收器都显示出不同的距离序列。



题解

设f[i]为区分i子树内部的节点最少需要在i内部放置多少个信号塔(这里假设已经能区分一个节点是否在i子树内)。

若节点i两个不同的儿子ch1,ch2,在ch1,ch2子树内部均没有信号塔,那么这两个子树内部相同深度的节点无法区分。因此节点i最多只能有1个儿子满足以其为根的子树内没有信号塔。


#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int INF=0x3f3f3f3f; const int N=5005; int n, f[N][N], sum; bool map[N][N]; char ch[N];   void DFS( int r, int fa ) {     if( f[r][fa]<INF ) return;     bool flg=0; f[r][fa]=0;     for( int i=1; i<=n; i++ )         if( i!=fa && map[r][i] ) {             DFS( i, r );             f[r][fa]+=max( 1, f[i][r] );             if( !f[i][r] ) flg=1;         }     f[r][fa]-=flg; }   int main() {scanf( "%d", &n );    for( int i=1; i<=n; i++ ) {         scanf( "%s", ch+1 );         for( int j=1; j<=n; j++ )             if( ch[j]=='Y' ) map[i][j]=1;     }     if( n<=1 ) { printf( "0\n" ); return 0; }     sum=n;     memset( f, 0x3f, sizeof f );     for( int i=1; i<=n; i++ ) {         DFS( i, 0 );        sum=min( sum, f[i][0]+1 );     }     printf( "%d\n", sum );     return 0; }