CodeForces - 618D Hamiltonian Spanning Tree 思维

13 篇文章 0 订阅

题目:点击打开链接

题意:n个点的无向完全图,所有边权都是y,给出一个生成树,并把生成树上的n-1条边边权改为x,求这个图的最小边权和的欧拉通路,只输出最小边权和

x > y 时应尽量使用生成树上的边,每个点只能经过一次,相当于一个链状结构,问题等于去掉最少的边使得树变成多条链

然后就不会了55555

看了题解才会,太强了,短短10行代码。。。。。

 贪心策略:每个点都尽可能的和子节点构成链状结构,从最底层叶子节点向上判断,因为我的父节点并不能很好的抉择和哪一个子节点构成链状结构,因此先解决子节点,如果子节点和子节点的子节点构成了一条不能和父节点连通的链,那就不选择这个子节点,从而可以选择其他还没有饱和的子节点。

x < y 时应尽量使用不在生成树上的边,当存在一个点,和其他点都直接连接时,这时不得不选择一个树上的点,

其余都可以找到一个条所有边都不在树上的欧拉通路

#include<bits/stdc++.h>
using namespace std;
int index, book[200005], use;
vector<int> w[200005];
int dfs(int fa, int x){
	int left = 2;
	for(int i = 0; i < w[x].size(); i++){
		if(w[x][i] == fa)
		continue;
		if(dfs(x, w[x][i]) && left){
			use++, left--;
		} 
	}
	return left;
}
int main(){
	int n, u, v;
	long long x, y;
	cin >> n >> x >> y;
	for(int i = 1; i < n; i++){
		scanf("%d %d", &u, &v);
		w[u].push_back(v);
		w[v].push_back(u);
		book[u]++, book[v]++;
	}
	if(x <= y){
		dfs(0, 1);
		cout << use * x + (n - 1 - use) * y << endl;
	}
	else{
		int flag = 0;
		for(int i = 1; i <= n; i++){
			if(book[i] == n - 1)
			flag = 1;
		}
		cout << y * (n - 1 - flag) + flag * x << endl;
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值