列表

详情


NC20823. 小K的疑惑

描述

众所周知,小K是一只连NOIP2018初赛都没有过的蒟蒻,所以小K很擅长dfs+分块树,但是本题与dfs+分块树无关。

K现在心态爆炸了,因为小K被一道简单的数据结构题给卡住了,希望请你来解决它,但是小K又不想太麻烦你,于是将题面进行了简化(其实是出题人懒得写题面了233333

    Bob有𝑁个点的树,每条边的长度有一个边权,现在定义𝑑𝑖𝑠(𝑖,𝑗)代表第𝑖个点到第𝑗个点的距离模2之后的结果。问有多少(𝑖,𝑗,𝑘)满足,𝑑𝑖𝑠(𝑖,𝑗) = 𝑑𝑖𝑠(𝑗,𝑘) = 𝑑𝑖𝑠(𝑖,𝑘)


输入描述

第一行一个整数𝑁代表点的数量。

接下来𝑁 − 1行每行三个数𝑠,𝑒,𝑑代表有一条在𝑠,𝑒之间长度为𝑑的边。

输出描述

一行一个整数代表有多少对(𝑖,𝑗,𝑘)满足条件。

示例1

输入:

3
1 2 3
1 3 4

输出:

9

原站题解

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

C++14(g++5.4) 解法, 执行用时: 17ms, 内存消耗: 12504K, 提交时间: 2020-08-19 12:02:18

#include<bits/stdc++.h>
using namespace std;
int n;
long long cnt[2];
struct node{
	int v,w;
	node(int vv,int ww):v(vv),w(ww){}
};
vector<node>g[500010];
void dfs(int u,int fa,int val){
	cnt[val]++;
	for(int i=0;i<g[u].size();i++){
		int v=g[u][i].v,w=g[u][i].w;
		if(v==fa){
			continue;
		}
		dfs(v,u,(val+w)%2);
	}
}
int main(){
	ios::sync_with_stdio(0);
	cin>>n;
	for(int i=1,x,y,z;i<n;i++){
		cin>>x>>y>>z;
		g[x].push_back(node(y,z));
		g[y].push_back(node(x,z));
	}
	dfs(1,-1,0);
	cout<<cnt[0]*cnt[0]*cnt[0]+cnt[1]*cnt[1]*cnt[1];
	return 0;
}

C++11(clang++ 3.9) 解法, 执行用时: 13ms, 内存消耗: 1248K, 提交时间: 2020-02-27 18:36:10

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,i,s,e,d,x=0,y=0;
vector<pair<ll,ll> >a[10005];
void dfs(ll m,ll q,ll l)
{
	if(l%2) y++;
	else x++;
	for(auto it:a[m])
	if(it.first!=q)
	dfs(it.first,m,(l+it.second)%2);
}
int main()
{
	cin>>n;
	for(i=1;i<n;i++)
	{
		cin>>s>>e>>d;
		a[s].push_back({e,d%2});
		a[e].push_back({s,d%2}); 
	}
	dfs(1,0,0);
	cout<<x*x*x+y*y*y;
}

上一题