Hamiltonian Spanning Tree CodeForces - 618D (思维)

A group of n cities is connected by a network of roads. There is an undirected road between every pair of cities, so there are roads in total. It takes exactly y seconds to traverse any single road.

A spanning tree is a set of roads containing exactly n - 1 roads such that it’s possible to travel between any two cities using only these roads.

Some spanning tree of the initial network was chosen. For every road in this tree the time one needs to traverse this road was changed from y to x seconds. Note that it’s not guaranteed that x is smaller than y.

You would like to travel through all the cities using the shortest path possible. Given n, x, y and a description of the spanning tree that was chosen, find the cost of the shortest path that starts in any city, ends in any city and visits all cities exactly once.

Input
The first line of the input contains three integers n, x and y (2 ≤ n ≤ 200 000, 1 ≤ x, y ≤ 109).

Each of the next n - 1 lines contains a description of a road in the spanning tree. The i-th of these lines contains two integers ui and vi (1 ≤ ui, vi ≤ n) — indices of the cities connected by the i-th road. It is guaranteed that these roads form a spanning tree.

Output
Print a single integer — the minimum number of seconds one needs to spend in order to visit all the cities exactly once.

Example
Input
5 2 3
1 2
1 3
3 4
5 3
Output
9
Input
5 3 2
1 2
1 3
3 4
5 3
Output
8
Note
In the first sample, roads of the spanning tree have cost 2, while other roads have cost 3. One example of an optimal path is .

In the second sample, we have the same spanning tree, but roads in the spanning tree cost 3, while other roads cost 2. One example of an optimal path is .

代码

#include<iostream>
#include<cstdio>
#include<stack>
#include<algorithm>
#include<queue>
#include<cstring>
#include<cmath>

using namespace std;
int n,x,y;
int num=0;
vector<int>graph[200005];
bool dfs(int root,int fa)
{
    int d=2;
    for(int i=0;i<graph[root].size();i++)
    {
        int v=graph[root][i];
        if(v==fa)
            continue;
        if(dfs(v,root)&&d)
          num++,d--;
    }
    return d>0;
}
int main()
{
    cin>>n>>x>>y;
    int sign=false;
    int p1,p2;
    for(int i=1;i<n;i++)
    {
        scanf("%d%d",&p1,&p2);
        graph[p2].push_back(p1);
        graph[p1].push_back(p2);
        if(graph[p1].size()==n-1)
            sign=true;
        if(graph[p2].size()==n-1)
            sign=true;
    }
    if(x>y)
    {
        if(sign)
            num++;
    }
    else
        dfs(1,-1);
    cout<<(long long)num*x+(long long)(n-1-num)*y<<endl;
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 7-1哈密顿回路是指一条经过图中所有顶点恰好一次的回路。在图论中,哈密顿回路是一个经典问题,其求解难度较大。对于一些特殊的图,如完全图和正则图,哈密顿回路的存在性已经得到了证明。但对于一般的图,目前还没有有效的算法可以在多项式时间内求解。 ### 回答2: 7-1 Hamiltonian cycle是指一个无向图中,经过每个点恰好一次的简单路径,称之为Hamiltonian cycle。如果一个无向图有Hamiltonian cycle,那么它就是一个Hamiltonian图。 Hamiltonian cycle问题是研究如何确定一个无向图中是否存在Hamiltonian cycle的问题,寻找这个问题的答案是计算机科学领域的一个重要课题。 目前,还没有发现一个可以解决所有情况的通用算法,这导致了这个问题的很多变种研究,例如,求解Hamiltonian路径和Hamiltonian环的问题,寻找最长、最短的Hamiltonian路径等等。此外,这个问题也引起了很多数学家的研究兴趣,他们试图证明这个问题的正确性。 虽然寻找一个图的Hamiltonian cycle问题是一个非常困难的问题,但已经被证明,当满足一定条件时,这个问题是可以在多项式时间内解决的。这个问题的关键在于如何确定判断是否存在Hamiltonian cycle的特征。 在实际应用中,Hamiltonian cycle问题与路线和规划问题有很大关联。例如,对于一些必须经过所有节点的计算机网络或路线规划问题,Hamiltonian cycle问题可以有效地应用于设计最优的路线方案。 总之,7-1 Hamiltonian cycle问题是一个非常重要的计算机科学问题,虽然该问题没有通用的解决方案,但已经有很多专家致力于解决这个问题,相信在未来,我们会找到更有效、更高效的算法来解决这个问题。 ### 回答3: 哈密顿回路是指一条经过图中每个顶点并且仅经过一次的闭合路径,其名称来源于爱尔兰数学家和物理学家威廉·哈密顿。这个概念是 NP 难问题之一,因此在复杂性理论的研究中受到广泛的关注。 在数学上,我们可以用一个图论的视角来理解哈密顿回路的概念。一个图是由一组顶点和它们之间的边构成的数学对象。如果一个图中存在一条经过所有顶点的路径,则称该图具有哈密顿路径。如果这条路径是闭合的,也就是说路径的最后一个顶点与第一个顶点相连,则称该图具有哈密顿回路。哈密顿回路是所有哈密顿路径的一类特殊情形,因为它可以被看作是一个哈密顿路径的起点和终点相同的特殊图。 从实际应用的角度来看,哈密顿回路的限制条件使其具有很高的计算复杂度。因为必须遍历到每个顶点,而且顶点只能经过一次,因此尝试找到一个图的哈密顿回路相当困难。实际上,对于一些有着特定的性质的图,哈密顿回路的存在问题可以使用一些算法解决。然而,对于大多数图而言,哈密顿回路的问题依然是难以解决的 NP 难问题。这种限制性质使得哈密顿回路成为了复杂性理论的重要研究领域之一。 总之,哈密顿回路是图论中的一个经典深度问题,其限制性质使得在实际应用中非常困难。然而,在理论研究中,在寻找哈密顿回路问题上的努力有助于对计算复杂度的理解和解决 NP 难问题提供新的视角和新的方法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值