【BZOJ】【P3573】【Hnoi2014】【米特运输】【题解】【map】

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3573

首先我们学好语文读懂题意

然后假设我们知道了根结点的值,那么显然整棵树就确定了

那么我们枚举每一个点作为不变点,计算根节点的值,把相同的值扔进map or hash 里

统计相同的个数

Code:

#include<map>
#include<cmath>
#include<vector>
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=5e5+5;
const double eps=1e-6;
typedef long long LL;
vector<int>G[maxn];
int fa[maxn],n;
double c[maxn],a[maxn],t[maxn];
int getint(){
	int res=0;char c=getchar();
	while(!isdigit(c))c=getchar();
	while(isdigit(c))res=res*10+c-'0',c=getchar();
	return res;
}
void dfs(int u){
	for(int i=0;i<G[u].size();i++){
		int v=G[u][i];
		if(v!=fa[u]){
			fa[v]=u;
			c[v]=c[u]+log(G[u].size()-(u!=1));
			dfs(v);		
		}
	}
}
map<double,int>M;
int dcmp(double x){return x<-eps?-1:x>eps;}
bool equal(double a,double b){return !dcmp(a-b);}
int main(){
	n=getint();
	for(int i=1;i<=n;++i)a[i]=log(getint());
	for(int i=1;i<n;i++){
		int u=getint(),v=getint();
		G[u].push_back(v);
		G[v].push_back(u);
	}dfs(1);
	map<double,int>::iterator it;
	for(int i=2;i<=n;i++){
		t[i]=a[i]+c[i];
		it=M.lower_bound(a[i]+c[i]-1e-7);
		if(it==M.end()||!equal(it->first,a[i]+c[i]))M[a[i]+c[i]]++;
		else it->second++;
	}int ans=n;
	it=M.lower_bound(a[1]-1e-7);
	if(it!=M.end()&&equal(it->first,a[1]))ans=min(ans,n-it->second-1);
	for(it=M.begin();it!=M.end();it++)ans=min(ans,n-it->second);
	cout<<ans<<endl;
	return 0;
}


你可能感兴趣的:(bzoj)