cf 646 E. Tree Shuffling

贪心做,每次选ai最小的点向下遍历,然后做最大交换次数。 把剩余的(1个0或1个1存在根结点) 在继续这个过程就行 我们可以推断 走过的点一定不会再走(再走肯定不会更优) 

#include
using namespace std;
typedef long long ll;
const int N = 2e5+10;
ll a[N];
int fa[N],b[N],c[N],cur,h[N],nex[N<<1],to[N<<1],vis[N],re[N][2];
ll ans;
void add_edge(int x,int y){
	to[++cur]=y;nex[cur]=h[x];h[x]=cur;
}
void dfs(int u,int f){
	fa[u]=f;
	for(int i = h[u]; i; i=nex[i]){
		if(f!=to[i]){
			dfs(to[i],u);
		}
	}
}
void dfs1(int rt,int u){
	if(vis[u]) return;
	vis[u]=1;
	re[rt][0]+=(b[u]!=c[u]&&(b[u]==0));
	re[rt][1]+=(b[u]!=c[u]&&(b[u]==1));
	for(int i = h[u]; i; i = nex[i]){
		int v = to[i];
		if(v!=fa[u]&&vis[to[i]]){
			re[rt][0]+=re[to[i]][0];
			re[rt][1]+=re[to[i]][1];
		}
		if(v!=fa[u]&&!vis[to[i]]){
			dfs1(rt,v);
		}
	}
}
struct node{
	ll a;
	int b,c,id;
	bool operator <(const node &x) const{
		return a

 

你可能感兴趣的:(codeforces)