[NOIP模擬賽]TPS

題目描述
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; 
}


發佈了101 篇原創文章 · 獲贊 7 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章