1 条题解

  • 0
    @ 2025-10-8 16:50:08

    80分超时无启发式代码:

    #include <bits/stdc++.h>
    using namespace std;
    const int N=2e5+10;
    vector<int> G[N];
    int n, tsp, dfn[N], _dfn[N], siz[N], col[N], cnt[N], ans[N], tot;
    
    void dfs1(int x, int xfa) {
        dfn[x] = ++tsp; _dfn[tsp] = x;
        siz[x] = 1;
        for(int y : G[x]) if(y != xfa) {
            dfs1(y, x);
            siz[x] += siz[y];
        }
    }
    
    void add(int x) { cnt[col[x]]++; if(cnt[col[x]] == 1) tot++; }
    void del(int x) { cnt[col[x]]--; if(cnt[col[x]] == 0) tot--; }
    
    void dfs2(int x, int xfa) {
        for(int y : G[x]) if(y != xfa) dfs2(y, x);
        
        for(int i = 0; i < siz[x]; i++) add(_dfn[dfn[x] + i]);
        ans[x] = tot;
        
        for(int i = 0; i < siz[x]; i++) del(_dfn[dfn[x] + i]);
    }
    
    int main() {
        scanf("%d", &n);
        for(int i = 1; i <= n; i++) scanf("%d", &col[i]);
        for(int i = 1, x, y; i < n; i++) {
            scanf("%d%d", &x, &y);
            G[x].push_back(y);
            G[y].push_back(x);
        }
        tsp = 0; dfs1(1, 0);
        memset(cnt, 0, sizeof(cnt));
        tot = 0; dfs2(1, 0);
        for(int i = 1; i <= n; i++) printf("%d ", ans[i]);
        return 0;
    }
    

    标程:

    #include<bits/stdc++.h>
    using namespace std;
    const int N=2e5+5;
    vector<int> G[N];
    int n,tsp,dfn[N],_dfn[N],siz[N],son[N],col[N],cnt[N],ans[N],tot;
    void dfs1(int x, int xfa)
    {
    	dfn[x]=++tsp; _dfn[tsp]=x;
    	siz[x]=1;son[x]=-1;
    	for(int y:G[x])if(y!=xfa)
    	{
    		dfs1(y,x);
    		siz[x]+=siz[y];
    		if(son[x]==-1 || siz[son[x]]<siz[y])son[x]=y;
    	}
    }
    void add(int x){cnt[col[x]]++;if(cnt[col[x]]==1)tot++;}
    void del(int x){cnt[col[x]]--;if(cnt[col[x]]==0)tot--;}
    void dfs2(int x, int xfa)
    {
    	for(int y:G[x])if(y!=xfa && y!=son[x])dfs2(y,x);
    	if(son[x]>0)dfs2(son[x],x);
    	
    	for(int i=0;i<siz[x];i++)
        {
            if(_dfn[dfn[x]+i]==son[x]){i=i+siz[son[x]]-1;continue;}
            add(_dfn[dfn[x]+i]);
        }
    	ans[x]=tot;
    
    	if(son[xfa]!=x) 
    	{
    		for(int i=0;i<siz[x];i++)del(_dfn[dfn[x]+i]);
    	}
    }
    int main() 
    {
        scanf("%d",&n);for(int i=1;i<=n;i++) scanf("%d",&col[i]);
        for(int i=1,x,y;i<n;i++) 
        {
            scanf("%d%d",&x,&y);
            G[x].push_back(y);
            G[y].push_back(x);
        }
        tsp=0; dfs1(1,0);
        memset(cnt,0,sizeof(cnt));
        tot=0;dfs2(1,0);
        for(int i=1; i<=n; i++) printf("%d ",ans[i]);
        return 0;
    }
    
    • 1

    D32*【树上启发式合并】子树的不同颜色数[洛谷U41492改编]

    信息

    ID
    358
    时间
    300ms
    内存
    256MiB
    难度
    8
    标签
    递交数
    530
    已通过
    73
    上传者