其他分享
首页 > 其他分享> > CSP2019树上的数

CSP2019树上的数

作者:互联网

我没有话说

Code:

#include<bits/stdc++.h>
using namespace std;
char buf[1<<20],*p1,*p2;
#define GC (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?0:*p1++)
//#define GC getchar()
template<class T> inline void read(T &n){
    char ch=GC;T w=1,x=0;
    while(!isdigit(ch)){if(ch=='-') w=-1;ch=GC;}
    while(isdigit(ch)){x=(x<<3)+(x<<1)+(ch^48);ch=GC;}
    n=x*w;
}
const int MAXN = 2e3 + 3;
int n , head[MAXN] , cnt;
struct node{
    int to , next;
}G[MAXN<<1];
int flag[MAXN] , from[MAXN] , p[MAXN] , rd[MAXN];
struct edge{
    int fa[MAXN] , siz[MAXN];
    bool prev[MAXN] , ne[MAXN]; 
}s[MAXN];
int fir[MAXN] , las[MAXN];
inline void add_edge( int x , int y ){
    G[++cnt].to = y , G[cnt].next = head[x];
    head[x] = cnt;
}
int findSet( int now , int x ){
    if( x != s[now].fa[x] ) s[now].fa[x] = findSet( now , s[now].fa[x] );
    return s[now].fa[x];
}
inline void unionSet(int now ,  int x , int y ){
    int u = findSet( now , x ) , v = findSet( now ,y );
    if( s[now].siz[u] < s[now].siz[v] ) swap( u , v );
    s[now].siz[u] += s[now].siz[v];
    s[now].fa[v] = u;
}
inline int sizeSet( int now , int x ){
    x = findSet( now , x );
    return s[now].siz[x];
}
inline void dfs( int x,  int from_ ){ 
    if( from_ && !las[x] && !s[x].ne[from_] && !( fir[x] && findSet( x , fir[x] ) == findSet( x , from_) && sizeSet( x , fir[x] ) < rd[x] ) )
        flag[x] = 1;
    for( int i = head[x] ; i ; i = G[i].next ){
        int v = G[i].to , id = i / 2;
        if( id == from_ ) continue;
        //printf( "%d\n" , v );
        if( !from_ ){
            if( fir[x] || s[x].prev[id]) continue;
            if( las[x] && findSet( x , id ) == findSet( x , las[x] ) && sizeSet( x , id ) < rd[x] ) continue;
            from[v] = i; 
             dfs( v , id );
         }
         else{
             if( from_ == las[x] || id == fir[x] || findSet( x , from_) == findSet( x , id ) || s[x].ne[from_] || s[x].prev[id] ) continue;
             if( fir[x] && las[x] && findSet( x , fir[x] ) == findSet( x , from_ ) && findSet( x , las[x] ) == findSet( x , id ) && sizeSet( x , fir[x])+ sizeSet( x , las[x] ) < rd[x] ) continue;
            from[v] = i;
             dfs( v , id );
         }
    }
}
inline void modify( int x , int y ){
    int last = 0;
    while( from[y] ){
        int id = from[y] >> 1;
        if( !last ){
             las[y] = id;
        }
        else{
            s[y].ne[id] = s[y].prev[last] = 1;
            unionSet( y , id , last );
        }
        last = id;
        y = G[from[y]^1].to;
    }
    fir[x] = last;
}
int main(){
    int t;scanf( "%d" , &t );
    while( t -- ){
        scanf( "%d" , &n );
        for( int i = 1 ; i <= n ; i ++ )
            scanf( "%d" , &p[i] );
        for( int i = 1 ; i <= n ;  i ++ ){
            fir[i] = las[i] = 0;
            for( int j = 1 ; j <= n ; j ++ )
                s[i].fa[j] = j , s[i].prev[j] = 0 , s[i].ne[j] = 0 , s[i].siz[j] = 1;        
            flag[i] = from[i] = 0;
            head[i] = 0;
            rd[i] = 0;
        }
        memset( G , 0 , sizeof( G)) ;
        cnt = 1;
        for( int i = 1 ; i < n ; i ++ ){
            int x , y;scanf( "%d%d" , &x , &y );
            add_edge( x , y );
            add_edge( y , x );
            rd[x] ++ , rd[y] ++;
        }
        for( int i = 1 ; i <= n ; i ++ ){
            dfs( p[i] , 0 );
        //    printf( "ss%d\n", p[i] );
            for( int j = 1 ; j <= n ; j ++ ){
                if( flag[j] ){
                    modify( p[i] , j );
                    printf( "%d " , j );
                    break;
                }
            }
            for( int j = 1 ; j <= n ; j ++ )
                flag[j] = from[j] = 0;
        }
        printf( "\n" );
    }
    
}

标签:树上,CSP2019,int,findSet,&&,MAXN,now,id
来源: https://blog.csdn.net/m0_63685780/article/details/121063396