所驼门王的宝藏
一眼就是\(tarjan\)缩点+\(dag\)上\(dp\).
原题数据并没有什么难点,直接暴力\(vector,map\)建边就\(A\)了。
但本质上这只是对没有宝藏的点的一种优化,如果某列或者某行全是宝藏,这个优化没有一点用。
然后数据加强了。。。。
我们需要一个技巧,可以让上限时空复杂度都降下来。
对每一行,每一列建一个虚点,虚点连向这一行,列上的所有宝藏。
如果一个点是横天门,纵,,门,就让这个点向虚点建边,进而达到了向该列所有点建边的效果。
注意统计答案的时候不要统计虚点。
code
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#include <map>
#define int long
#define R register int
#define printf Ruusupuu = printf
#define mp( x , y ) make_pair( x , y )
using namespace std ;
typedef long long L ;
typedef long double D ;
typedef unsigned long long G ;
const int N = 3e5 + 10 ;
int Ruusupuu ;
inline int read(){
int w = 0 ; bool fg = 0 ; char ch = getchar() ;
while( ch < '0' || ch > '9' ) fg |= ( ch == '-' ) , ch = getchar() ;
while( ch >= '0' && ch <= '9' ) w = ( w << 1 ) + ( w << 3 ) + ( ch ^ '0' ) , ch = getchar() ;
return fg ? -w : w ;
}
int n , ms , ks , cnt , cnts , tnt , gnt , head [N] , heads [N] , h [N] , l [N] , kk ;
int dfn [N] , low [N] , st [N] , kin [N] , top , dr [N] , f [N] , w [N] ; bool fg [N] ;
struct P{ int x , y , opt ; } a [N] ;
map< pair< int , int > , vector< int > > m ;
map< pair< int , int > , bool > hs ;
struct E{ int fr , to , next ; } e [N << 2] , es [N] ;
inline void add( int f , int t ){
e [++ cnt].fr = f ;
e [cnt].to = t ;
e [cnt].next = head [f] ;
head [f] = cnt ;
}
inline void adds( int f , int t ){
es [++ cnts].fr = f ;
es [cnts].to = t ;
es [cnts].next = heads [f] ;
heads [f] = cnts ;
}
void sc(){
n = read() , ms = read() , ks = read() ; kk = n ;
memset( head , -1 , sizeof( head ) ) ;
memset( heads , -1 , sizeof( heads ) ) ;
for( R i = 1 ; i <= n ; i ++ ){
a [i].x = read() , a [i].y = read() , a [i].opt = read() ;
if( !h [a [i].x] ) h [a [i].x] = ++ kk ;
if( !l [a [i].y] ) l [a [i].y] = ++ kk ;
add( h [a [i].x] , i ) ;
add( l [a [i].y] , i ) ;
m [mp( a [i].x + 1 , a [i].y + 1 )].push_back( i ) ;
m [mp( a [i].x + 1 , a [i].y )].push_back( i ) ;
m [mp( a [i].x , a [i].y + 1 )].push_back( i ) ;
m [mp( a [i].x - 1 , a [i].y - 1 )].push_back( i ) ;
m [mp( a [i].x , a [i].y - 1 )].push_back( i ) ;
m [mp( a [i].x - 1 , a [i].y )].push_back( i ) ;
m [mp( a [i].x + 1 , a [i].y - 1 )].push_back( i ) ;
m [mp( a [i].x - 1 , a [i].y + 1 )].push_back( i ) ;
}
for( R i = 1 ; i <= n ; i ++ ){
if( a [i].opt == 1 ) add( i , h [a [i].x] ) ;
if( a [i].opt == 2 ) add( i , l [a [i].y] ) ;
if( a [i].opt == 3 ){
pair< int , int > p = mp( a [i].x , a [i].y ) ;
for( R j = 0 ; j < m [p].size() ; j ++ )
if( i != m [p][j] ) add( i , m [p][j] ) ;
}
}
// for( R i = 1 ; i <= n ; i ++ ) for( R j = head [i] ; ~j ; j = e [j].next ) printf( "%ld %ld\n" , i , e [j].to ) ;
}
inline void tj( int x ){
dfn [x] = low [x] = ++ tnt ;
st [++ top] = x ; fg [x] = 1 ;
for( R i = head [x] ; ~i ; i = e [i].next ){
int y = e [i].to ;
if( !dfn [y] )
tj( y ) , low [x] = min( low [x] , low [y] ) ;
else if( fg [y] )
low [x] = min( low [x] , dfn [y] ) ;
}
if( dfn [x] == low [x] ){
int tmp ; gnt ++ ;
do{
tmp = st [top --] ;
fg [tmp] = 0 ;
kin [tmp] = gnt ;
if( tmp <= n ) w [gnt] ++ ;
}while( x != tmp ) ;
}
}
inline void topsort(){
queue< int > q ; memset( f , -0x3f , sizeof( f ) ) ;
for( R i = 1 ; i <= gnt ; i ++ ) if( !dr [i] ) {
f [i] = w [i] , q.push( i ) ;
}// printf( "%ld\n" , f [i] ) ;
while( !q.empty() ){
int t = q.front() ; q.pop() ;
for( R i = heads [t] ; ~i ; i = es [i].next ){
int y = es [i].to ;
f [y] = max( f [y] , f [t] + w [y] ) ;
// printf( "RE%ld %ld\n" , y , f [y] ) ;
dr [y] -- ; if( dr [y] == 0 ) q.push( y ) ;
}
}
int ans = 0 ;
for( R i = 1 ; i <= n ; i ++ )
ans = max( ans , f [i] ) ;
printf( "%ld\n" , ans ) ;
}
void work(){
for( R i = 1 ; i <= n ; i ++ ) if( !dfn [i] ) tj( i ) ;
for( R i = 1 ; i <= kk ; i ++ ){
for( R j = head [i] ; ~j ; j = e [j].next ){
int y = e [j].to ; if( !kin [i] || !kin [y] ) continue ;
if( kin [y] != kin [i] && !hs[mp( kin [i] , kin [y] )] )
adds( kin [i] , kin [y] ) , dr [kin [y]] ++ , hs [mp( kin [i] , kin [y] )] = 1 ;
}
}
// for( R i = 1 ; i <= n ; i ++ )
// printf( "BL%ld\n" , kin [i] ) ;
/* for( R i = 1 ; i <= n ; i ++ )
for( R j = heads [i] ; ~j ; j = es [j].next )
printf( "%ld %ld\n" , i , es [j].to ) ;*/
topsort() ;
}
signed main(){
sc() ;
work() ;
return 0 ;
}
$The \ light \ has \ betrayed \ me$

浙公网安备 33010602011771号