其他分享
首页 > 其他分享> > Hamiltonian Spanning Tree - CodeForces - 618D 【DFS 贪心】

Hamiltonian Spanning Tree - CodeForces - 618D 【DFS 贪心】

作者:互联网

题目链接

CF618D

题意

n个点,任意两点之间有一条无向边,每条边的权值都是y,现在给你一个生成树,这个生成树上的权值从y改成了x。问你现在遍历所有的点一次且仅一次的代价和最小是多少?
\((2\leq n \leq 200 000, 1\leq x,y \leq 10^9)\)

思路

代码

#include<bits/stdc++.h>
#define DEBUG1
using namespace std;
typedef long long ll;
const int MAXN=200005;
struct Edge{
	int to,next;
}edge[MAXN<<1];
int head[MAXN],deg[MAXN];
int cnt,len;
ll ans,n,x,y;
void add_edge(int u,int v){
	edge[++cnt].to=v;
	edge[cnt].next=head[u];
	head[u]=cnt;
	edge[++cnt].to=u;
	edge[cnt].next=head[v]; 
	head[v]=cnt;
}
int tmp=0;
bool dfs(int u,int fa){
	#ifdef DEBUG
	tmp++;
	if(tmp>=20) return false;
	#endif
	int tot=2;
	for(int i=head[u];i;i=edge[i].next){
		int to = edge[i].to;
		#ifdef DEBUG
			printf("u:%d,fa:%d,to:%d,tot:%d\n",u,fa,to,tot);
		#endif
		if(to==fa) continue;
		//dfs(to,v):如果这个为false则表明子节点已经用掉了2条边了
		//tot:如果tot==0,那么说明这个点已经用掉2条边了 		
		// 这两种情况下,这一条边都不能用了
		if(dfs(to,u)&&tot){
			len++;
			tot--;
		}
	}
	return tot;
}
int main()
{
	scanf("%lld%lld%lld",&n,&x,&y);
	int u,v;
	bool flag=false;
	for(ll i=1;i<n;i++){
		scanf("%d%d",&u,&v);
		add_edge(u,v);
		deg[u]++;
		deg[v]++;
		if(deg[u]==n-1||deg[v]==n-1)flag=true;
	}
	if(x>=y){
		if(flag) printf("%lld\n",y*(n-2)+x);
		else printf("%lld\n",y*(n-1));
		return 0;
	}
	else{
		dfs(1,0);
		ans=len*x+(n-1-len)*y;
		printf("%lld\n",ans);
	}
	return 0;
} 

标签:618D,Hamiltonian,int,Tree,tot,leq,dfs,printf,lld
来源: https://www.cnblogs.com/xuwanwei/p/12837850.html