제출 #409884

#제출 시각아이디문제언어결과실행 시간메모리
409884CaroLindaThe Xana coup (BOI21_xanadu)C++14
100 / 100
101 ms15328 KiB
#include <bits/stdc++.h>

#define ll long long
#define all(x) x.begin(),x.end()

const int MAXN = 1e5+10 ;

using namespace std ;

int N ;
int color[MAXN] ;
int dp[MAXN][2][2] ; //color, should click
vector<int> adj[MAXN] ;

void dfs(int x, int par )
{
	bool is_leaf = true ;

	for(auto e : adj[x])
	{
		if(e == par ) continue ;
		
		dfs(e,x) ;
		is_leaf = false ;
	}

	if(is_leaf)
	{

		dp[x][0][0] = 0 ;
		dp[x][0][1] = N+5 ;
		dp[x][1][0] = N+5 ;
		dp[x][1][1] = 1 ;

		return ;
	}

	int ans = 0 ;
	int min_coin = 2*N+10 ;
	int qtd = 0 ;

	//should not click
	for(auto e : adj[x] )
	{
		if(e == par ) continue ;

		if( dp[e][ color[e] ][0] <= dp[e][ color[e] ][1] )
		{
			ans += dp[e][ color[e] ][0] ;
			min_coin = min(min_coin , dp[e][ color[e] ][1] - dp[e][ color[e] ][0] ) ;
		}
		else
		{
			ans += dp[e][ color[e] ][1] ;
			min_coin = min( min_coin , dp[e][ color[e] ][0] - dp[e][ color[e] ][1] ) ;
			qtd ^= 1 ;
		}
	}

	if(qtd)
	{
		dp[x][1][0] = ans ;
		dp[x][0][0] = ans+min_coin ;
	}
	else
	{
		dp[x][1][0] = ans+min_coin ;
		dp[x][0][0] = ans ;
	}

	//should click
	ans = 1 ;
	min_coin = 2*N+10 ;
	qtd = 0 ;

	for(auto e : adj[x] ) 
	{
		if(e == par ) continue ;

		int mx = max( dp[e][!color[e]][0] , dp[e][!color[e]][1] ) ;
		int mn = min( dp[e][!color[e]][0] , dp[e][!color[e]][1] ) ;

		ans += mn ;
		min_coin = min(min_coin , mx-mn ) ;

		if( dp[e][!color[e]][0] > dp[e][ !color[e] ][1] ) qtd ^= 1 ;

	}

	if( qtd )
	{
		dp[x][0][1] = ans ;
		dp[x][1][1] = ans+min_coin ;
	}
	else
	{
		dp[x][0][1] = ans+min_coin ;
		dp[x][1][1] = ans; 
	}

	for(int i = 0 ; i < 2 ; i++ )
		for(int j = 0 ; j< 2 ; j++ )
			dp[x][i][j] = min(dp[x][i][j] , N+5) ;

	/*cout << x << endl ;
	for(int i = 0 ; i < 2 ; i++ , cout << endl )
		for(int j = 0 ; j < 2 ; j++ ) cout << dp[x][i][j] <<" " ;
	cout << endl ;*/

}

int main()
{
	scanf("%d", &N ) ;
	for(int i = 1 , u ,v ; i < N ; i++ )
	{
		scanf("%d %d", &u, &v ) ;
		adj[u].push_back(v) ;
		adj[v].push_back(u) ;
	}
	for(int i = 1 ; i <= N ; i++ ) scanf("%d", &color[i] ) ;

	dfs(1,-1) ;

	int ans = min( dp[1][color[1]][0] , dp[1][color[1]][1] ) ;

	if(ans == N+5 ) printf("impossible\n") ;
	else printf("%d\n" , ans ) ;
}

컴파일 시 표준 에러 (stderr) 메시지

xanadu.cpp: In function 'int main()':
xanadu.cpp:114:7: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  114 |  scanf("%d", &N ) ;
      |  ~~~~~^~~~~~~~~~~
xanadu.cpp:117:8: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  117 |   scanf("%d %d", &u, &v ) ;
      |   ~~~~~^~~~~~~~~~~~~~~~~~
xanadu.cpp:121:38: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  121 |  for(int i = 1 ; i <= N ; i++ ) scanf("%d", &color[i] ) ;
      |                                 ~~~~~^~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...