列表

详情


NC208151. 月出皎兮,佼人僚兮。

描述

月出皎兮。佼人僚兮。舒窈纠兮。劳心悄兮。

 机缘巧合之下,一女误入诗经之境。少女在桥上,望尽千里壮阔千山。只见画面瞬转,忽不慎跌入荷塘深处,左右尽是海草纠缠。少女心中惶惶,只见水中突然横现一行字,写着“
    给一棵树有n个节点,根节点为1。
    每个点有一个颜色,并且有一个权值,为当前这个节点颜色的数量。
    对每个点输出,当前点以及子树中的最大匹配数。
    当且仅当颜色不同可以匹配。
”。
你可以解救被困水中的少女吗?

比如:
颜色1的权值和为3,颜色2的权值和为2,那么最大匹配数就是2。
颜色1的权值和为3,颜色2的权值和为2,颜色3的权值和为1,那么最大匹配数就是3。


输入描述

第一行输入一个n,代表树的节点个数。
接下来输入n-1行,每行2个数:u,v代表存在一条u到v的边。保证树连通。
接下来输入n行,每行2个数:x,y,代表点i的颜色和数量。
节点个数1<=n<=2e5
颜色总数1<=x<=2e5
每个点的数量1<=y<=1e3

输出描述

输出有n行,从1到n分别代表当前点以及子树中的最大匹配。

示例1

输入:

4
1 2
1 3
2 4
1 3
3 1
2 2
2 3

输出:

4
1
0
0

说明:

显然3,4号点只有1种颜色,故无法匹配,所以最大匹配为0.
对于2号点,颜色3有1个,颜色2有3个,所以最大匹配为1.
对于1号店,颜色1有3个,颜色2有5个,颜色3有1个,可以发现最大匹配为4.

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 732ms, 内存消耗: 26076K, 提交时间: 2020-06-22 13:18:28

#include<bits/stdc++.h>
using namespace std;
const int N = 2e5+5;
vector<int>adj[N];
int color[N], cnt[N], n, u, v, ans[N];
unordered_map<int, int>* DFS(int cur, int parent)
{
	unordered_map<int, int> *pmap = new unordered_map<int, int>, *pson = 0;
	(*pmap)[color[cur]] = cnt[cur];
	for(auto r : adj[cur])
		if(r != parent)
		{
			pson = DFS(r, cur);
			for(auto s : *pson)
				(*pmap)[s.first] += s.second;
			delete pson;
			pson = 0;
		}
	int maxcnt = 0, sum = 0;
	for(auto r : *pmap)
	{
		maxcnt = max(maxcnt, r.second);
		sum += r.second;
	}
	if(sum < maxcnt*2)
		ans[cur] = sum - maxcnt;
	else
		ans[cur] = sum / 2;

	return pmap;
}
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n;
	for(int i = 1; i < n; i++)
	{
		cin >> u >> v;
		adj[u].push_back(v);
		adj[v].push_back(u);
	}
	for(int i = 1; i <= n; i++)
		cin >> color[i] >> cnt[i];
	DFS(1, 0);
	for(int i = 1; i <= n; i++)
		cout << ans[i] << endl;
}

C++11(clang++ 3.9) 解法, 执行用时: 736ms, 内存消耗: 83404K, 提交时间: 2020-07-04 11:46:48

#include<bits/stdc++.h>
using namespace std;
 
int a[200005],b[200005],ans[200005],sum[200005],Max[200005];
vector<int>R[200005];
map<int,int>T[200005];
void DFS(int x,int fa)
{
    int i,j;
    Max[x]=sum[x]=b[x],T[x][a[x]]+=b[x];
    for(i=0;i<R[x].size();i++)
    {
        j=R[x][i];
        if(j==fa)continue;
        DFS(j,x),sum[x]+=sum[j],Max[x]=max(Max[x],Max[j]);
        if(T[x].size()<T[j].size())swap(T[x],T[j]);
        for(auto k:T[j])T[x][k.first]+=k.second,Max[x]=max(Max[x],T[x][k.first]);
    }
    if(Max[x]*2>sum[x])ans[x]=sum[x]-Max[x];
    else ans[x]=sum[x]/2;
}
int main()
{
    int i,j,k,n;
    scanf("%d",&n);
    for(i=1;i<n;i++)
    {
        scanf("%d%d",&j,&k);
        R[j].push_back(k),R[k].push_back(j);
    }
    for(i=1;i<=n;i++)scanf("%d%d",&a[i],&b[i]);
    DFS(1,0);
    for(i=1;i<=n;i++)printf("%d\n",ans[i]);
}

上一题